Skip to content

Commit

Permalink
Remove excessive randomness
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewcmyers committed Nov 1, 2024
1 parent 62c8af3 commit 70bc4b4
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 34 deletions.
1 change: 1 addition & 0 deletions fulltext.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<script src="js/constrain-notes.js"></script>
<script src="js/colorize.js"></script>
<script src="js/italmath.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.5/seedrandom.min.js"></script>
<script id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<script>

Expand Down
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<script src="js/constrain-notes.js"></script>
<script src="js/colorize.js"></script>
<script src="js/italmath.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.5/seedrandom.min.js"></script>
<script id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<script>

Expand Down
6 changes: 6 additions & 0 deletions js/constrain-notes.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class LightStyle extends Constrain.Trees.TreeStyle {
}
}


class CFigure extends Constrain.Figure {
constructor(canvas, advance) {
super(canvas)
Expand All @@ -51,6 +52,7 @@ class CFigure extends Constrain.Figure {
this.setFadeColor("#eee")
this.boxw = 80
this.boxh = 20
this.rand = new Math.seedrandom("oodds")

if (advance) {
this.theAdvanceButton = this.advanceButton()
Expand Down Expand Up @@ -157,6 +159,10 @@ class CFigure extends Constrain.Figure {
lightStyle(specialEdges, specialNodes) {
return new LightStyle(this, specialEdges, specialNodes)
}
renderFrame(animating, frameInterval, frameLength) {
this.rand = new Math.seedrandom("oodds")
super.renderFrame(animating, frameInterval, frameLength)
}
}

Constrain.autoResize()
1 change: 1 addition & 0 deletions lecture.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<script src="js/constrain/constrain-graph.js"></script>
<script src="js/constrain/constrain-trees.js"></script>
<script src="js/constrain-notes.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.5/seedrandom.min.js"></script>
<script id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<script>
document.addEventListener('load', Constrain.autoResize)
Expand Down
19 changes: 11 additions & 8 deletions lectures/complexity/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ <h1>Asymptotic Complexity</h1>
computers, we can see that the shape of the curve has an underlying similarity. If we
plot the timing data for sufficiently large problem sizes \(n\), and
rescale the vertical axis to account for the relative speed of the computers,
we typically see a more well-behaved plot like the following:
we effectively zoom out from the origin, making
the experimental variation less and less important,
resulting in a well-behaved plot like the following:
</p>
<canvas id="idealized-runtime" style="width:600px; height:240px"></canvas>
<script class=graphics>
Expand Down Expand Up @@ -219,14 +221,15 @@ <h2>Deriving asymptotic complexity</h2>
On the other hand, if the ratio limits to infinity, \( f(n) \) is
<em>not</em> \( O(g(n)) \). (Using the definition of limits, both of these
shortcuts can be proved sound with respect to the definition of big-O,
choosing a value of \(k\) that for the first shortcut is strictly
larger than the ratio.)
choosing any value of \(k\) that for the first shortcut is strictly
larger than the ratio limit.)
</p>
<p>
To evaluate the limit of \( f(n)/g(n) \), L'Hôpital's rule often comes in handy.
When both \( f(n) \) and \( g(n) \) go to infinity as \( n \) goes to infinity, the ratio
\( f(n)/g(n) \) of the two functions has the same limit as the ratio of
their derivatives: \( f'(n)/g'(n) \).
To evaluate the limit of \( f(n)/g(n) \), L'Hôpital's rule often comes in
handy. When, as is often the case for complexity, both \( f(n) \) and \( g(n)
\) go to infinity as \( n \) goes to infinity, the ratio \( f(n)/g(n) \) of the
two functions has the same limit as the ratio of their derivatives: \(
f'(n)/g'(n) \).
</p>
<p>
For example, \( \ln n \) is \( O(n) \) because
Expand All @@ -235,6 +238,6 @@ <h2>Deriving asymptotic complexity</h2>
the derivative of \( \ln^k n \) is \( (k \ln^{k-1} n)/n\).
Since \( \ln n \) is \(O(n)\) so is \(\ln^2 n \), and therefore
\(ln^3 n\), and so on for any positive \(k\). (This is an argument by induction.)
No matter what power we raise \(\lg n\) to, it grows more slowly asymptotically than
In other words, no matter what power we raise \(\lg n\) to, it grows more slowly asymptotically than
any polynomial \(n^k\) with \(k&gt; 0\). This fact is useful because logarithmic
factors show up frequently in the analysis of algorithms.
23 changes: 13 additions & 10 deletions lectures/sorting/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ <h2>Merge sort</h2>
let r = rectangle()
pin(p1, r.ul())
pin(p2, r.lr())
label(text(italic("n"), (x == 0 ? "" : "/" + (1<<x)))).at(r.center())
label(text(whitespace(), italic("n"), (x == 0 ? "" : "/" + (1<<x)))).at(r.center())
.setFontSize(15 - x)
let m = average(p1.x(), p2.x())
level(x + 1, p1.toBottom(hs), point(minus(m, sep/2), plus(p2.y1(), hs)))
Expand Down Expand Up @@ -573,13 +573,15 @@ <h2>Merge sort</h2>
reason why merge sort is commonly used. Another is that its run time
is not only fairly low but is also predictable.
</p><p>
Merge sort is not quite as fast as the quicksort algorithm that we will see
next because it does extra copying into the temporary array.
Merge sort is not quite as fast as the quicksort algorithm that we discuss
next because it copies elements into the temporary array.
We can avoid some of the copying by exchanging the roles of <code>a</code> and <code>tmp</code> on
alternate recursive calls. This trick speeds up the algorithm slightly at the cost of more complex code.
alternate recursive calls. This trick speeds up the algorithm slightly at the cost of making the
code more complex.
It is actually possible to do an in-place merge in linear time, but in-place merging
is quite tricky and about 5 times slower in practice than using a separate array.
</p><p>
</p>
<p>
Another trick that is used to speed up merge sort is to use insertion
sort when the subarrays are small enough. For small arrays,
insertion sort is faster because \(k_1n^2\) is smaller than \(k_2n \lg n\)
Expand Down Expand Up @@ -707,8 +709,9 @@ <h3>Partitioning</h3>
the values they index will be on the correct side of the array and the
array can be partitioned between them. Finally, there is at least one
value <code>v</code> to the right of <code>i</code> such that <code>v ≥ p</code> and at least one value <code>v</code> to the left
of <code>j</code> such that <code>v ≤ p</code>. These values serve as <strong>sentinel values</strong> that
stop iteration from walking off either end of the array.
of <code>j</code> such that <code>v ≤ p</code>.
These values serve as <strong>sentinels</strong> that stop the algorithm
from walking off the end of the array.
</p>
<div class=figure>
<canvas id="qs-inv" style="height:80px; width:400px">
Expand Down Expand Up @@ -753,13 +756,13 @@ <h3>Partitioning</h3>
<p>
Interestingly, these inner loops do not need to do any bounds checking on
<code>i</code> and <code>j</code>, which makes them significantly more efficient.
The reason bounds checks are not needed is that the sentinel values in the array,
The reason bounds checks are not needed is alluded to above: the sentinel values in the array,
maintained by the loop invariant, stop the inner loops before they walk off
the ends of the array.
</p>
<p>
An example of partitioning will probably help understand what is going
on. We start out with the following array, with <code>p=5</code>:
An example of partitioning will probably help.
We start out with the following array, with <code>p=5</code>:
</p>
<pre>
5 2 6 7 1 9 3 8
Expand Down
34 changes: 18 additions & 16 deletions lectures/ssp/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,19 @@ <h2>Dijkstra's algorithm</h2>
</ul>

<p>
Dijkstra's algorithm starts with the root in the priority queue
at distance <code>0</code> (<code>v.dist = 0</code>), so it is gray. All other nodes are
at distance ∞ and are white. The algorithm then works roughly like BFS, except
that when node is popped from the priority queue, the node with
the <em>smallest</em> <code>v.dist</code> value among all those on
the queue is popped. When the algorithm completes,
The main loop of
Dijkstra's algorithm starts with the root node in the priority queue
at distance <code>0</code> (<code>root.dist = 0</code>), so it is gray. All other nodes are
at distance ∞ and are white. The algorithm then works similarly to BFS, except
that the gray node <code>g</code> that is popped from the priority queue is the one with
the <em>smallest</em> <code>dist</code> value among all those on
the queue. When the algorithm completes,
all reachable nodes are black and hold their true minimum distance.
</p>
<p>
Another key difference from BFS is that when an edge from a frontier
node to some node <code>v</code> is considered, it may lie on a shorter path to
To make nodes hold the correct distance, there is another change
from BFS. When an edge from a frontier
node <code>g</code> to some node <code>v</code> is considered, it may lie on a shorter path to
<code>v</code> than was previously known. In this case, the distance estimate to
<code>v</code> is lowered, and the priority queue must also be informed about
the change so that it can produce <code>v</code> perhaps earlier than it would
Expand Down Expand Up @@ -139,10 +141,10 @@ <h2>Dijkstra's algorithm</h2>
</pre>
<p>
Dijkstra's algorithm is an example of a <b>greedy algorithm</b>: an algorithm
in which simple local choices (like choosing the gray vertex with the smallest
<code>g.dist</code>) lead to globally optimal results (minimal distances
computed to all vertices). Many other problems, such as finding a minimum
spanning tree, can be solved by greedy algorithms. Other problems, such as
in which simple local choices (in this case, choosing the gray vertex with the smallest
value of <code>g.dist</code>) lead to globally optimal results (minimal distances
computed to all vertices). Many problems, such as finding minimum
spanning trees, can be solved by greedy algorithms. Other problems, such as
Traveling Salesperson,
cannot.
</p>
Expand Down Expand Up @@ -356,7 +358,7 @@ <h3>Correctness of Dijkstra's algorithm</h3>
vx = -uy, vy = ux
let bs_pts = [], s = dist/n
for (let i = 0; i <= n; i++) {
let off = 2*SQUIGGLE_HEIGHT*(Math.random()-0.5)
let off = 2*SQUIGGLE_HEIGHT*(this.figure.rand.double()-0.5)
if (i <= 2 || i >= n-2) off = 0
let x = x0 + ux * s * i + vx * off,
y = y0 + uy * s * i + vy * off
Expand Down Expand Up @@ -422,9 +424,9 @@ <h3>Correctness of Dijkstra's algorithm</h3>
but instead go via some other black node \(b\). By invariant part 1, we know \(b\)<code>.dist</code>\( ≤ g\)<code>.dist</code>, so any such interior path must be at least as long as the
preexisting interior path that goes from the roots directly to <code>b</code> and then
to <code>v</code>, and we know by invariant part 2 that <em>that</em> path is no
shorter than <code>v.dist</code>. Therefore, the third category of interior paths
cannot yield paths that are shorter than the existing paths to \(v\) that are summarized
by \(v\)<code>.dist</code>.
shorter than <code>v.dist</code>. Therefore, the third category of new interior paths
cannot yield paths that are shorter than the previously existing interior paths to \(v\),
which are already summarized by \(v\)<code>.dist</code>.
</p>
</ul>
</ol>
Expand Down

0 comments on commit 70bc4b4

Please sign in to comment.