Held Monday, December 6, 1999
Overview
Today, we consider a more efficient (but less intuitive) solution to
the shortest path problem. This solution is known as Dijrkstra's method.
It shares some ideas with Sierra's proposed solution.
Notes
- Exam 3 due.
- I am revamping the grading policies. It is likely that each exam
will be worth the same as each homework assignment.
- I was going to hand out class evaluations today, but that seems
like a bad idea after hearing your pre-class complaints.
Contents
Summary
- Exam 3 due.
- Dijkstra's shortest path algorithm
- Near the end of last class, Sierra suggested that we solve the
shortest path problem by using a priority queue.
- What did he mean by that?
- Let's consider the following undirected graph and find the
shorest path from A to E
G---H---I---J---K
| 0 1 2 1 |
3| |20
| 1 4 1 9 |
A---B---C---D---E
| | | |
9| 2| 0| |
| | | |
+---F---+ |
| 6 |
+-----------+
- A computer scientist named Dijkstra proposed an interesting strategy
for finding the shortest path from A to B.
- He suggested that we can find the shortest path from A
to B by finding the shortest path from A to all nodes in the graph.
(Talk about overkill.)
- His algorithm is generally used with the ``sum of weights'' metric.
- It may also work with selected other metrics.
- His algorithm assumes that edge weights are nonnegative.
- We'll divide the graph into two parts:
- SP.
The nodes whose shortest path we know. For these nodes, we'll store
the distance to that node and the path to that node.
- Est.
The nodes whose shortest path we don't know. For these nodes, we'll
store the shortest known distance to that node (which may not be
the shortest) and the corresponding path.
- Initially, Est contains all the nodes. The
distance from A to itself is 0, and the distance from A to every
other node is some distance greater than the largest distance
in the graph.
- At each step, we'll move one node from Est to SP.
After doing so, we'll update the estimated costs of all of its neighbors.
- Which node to we move? Node s, the one with the smallest
estimated distance.
- Why is this safe? Because the only way to reduce that distance would
be to pick another node, t from Est and have a path
from that node to s such that A to t to s
has smaller distance than our current estimate of the distance form
A to s. But that's not possible, since the cost function
is non-decreasing, and we already know that the cost from A to t
is at least as big as the cost from A to s.
- Note that instead of storing the path, we can simply store the previous
node in the path.
- Dijkstra's algorithm is another example of a greedy algorithm:
at each step in the algorithm, we pick a ``best'' node
- Here's a sample graph to consider. I've used an undirected graph because
the algorithm works equally well for undirected graphs and they're easier
to draw.
G
|
3|
| 1 4 1 9
A---B---C---D---E
| | | |
9| 2| 0| |
| | | |
+---F---+ |
| 6 |
+-----------+
- What is the shortest path from A to E? It may be hard to see
at first (not too hard, but nontrivial).
- Let's see what the algorithm tells us.
- Initially,
- SP = {
}
- Est = {
A:(0,empty)
B:(100,?)
C:(100,?)
D:(100,?)
E:(100,?)
F:(100,?)
G:(100,?)
}
- The smallest distance in that graph is the distance to A, so we
- Move A to SP
- Update the distances to all of its neighbors (B, F, and G which now
have actual paths and distances)
- We now have the following information
- SP = {
A:(0,empty)
}
- Est = {
B:(1,A)
G:(3,A)
F:(9,A)
C:(100,?)
D:(100,?)
E:(100,?)
}
- We move B to SP and update its neighbors. We now know a
path to C and a better path to F (A->B->F has cost 1 + 2 = 3).
- SP = {
A:(0,empty)
B:(1,A)
}
- Est = {
F:(3,B)
G:(3,A)
C:(5,B)
D:(100,?)
E:(100,?)
}
- We could then move F or G to SP. Let's say that we move
F. We now know a shorter path to C (A->B->F->C has cost 3, A->B->C
had cost 5) and a path to E.
- SP = {
A:(0,empty)
B:(1,A)
F:(3,B)
}
- Est = {
G:(3,A)
C:(3,F)
E:(9,F)
D:(100,?)
}
- We can then move G or C to SP. Let's say that we move G.
G has no neighbors, so there are no other changes.
- SP = {
A:(0,empty)
B:(1,A)
F:(3,B)
G:(3,A)
}
- Est = {
C:(3,F)
E:(9,F)
D:(100,?)
}
- Next we move C. We can then update the distance to D.
- SP = {
A:(0,empty)
B:(1,A)
F:(3,B)
G:(3,A)
C:(3,F)
}
- Est = {
D:(4,C)
E:(9,F)
}
- We then move D. Note that even though there is an edge from
D to E, it doesn't give us any better path, so we don't change
the entry for E.
- SP = {
A:(0,empty)
B:(1,A)
F:(3,B)
G:(3,A)
C:(3,F)
D:(4,C)
}
- Est = {
E:(9,F)
}
- We move E and we're done
- SP = {
A:(0,empty)
B:(1,A)
F:(3,B)
G:(3,A)
C:(3,F)
D:(4,C)
E:(9,F)
}
- Est = {
}
- What's the shortest path from A to E? It has cost 9 and is the
reverse of (E-F-B-A). How did I get that path? I read it off
from the second elements of SP.
- What's the running time of this algorithm?
- During initialization, we visit each node once, which should be
O(n) in any reasonable implementation.
- In the main loop, we remove each node from Est once, so
there are O(n) repetitions of the main loop.
- We look at each edge twice (one for each node connected to the
edge), so the ``update distances'' part takes O(m) across
the whole algorithm. (m is the number of edges)
- How long does it take to find the smallest distance in Est?
For the structures we've learned, O(n).
- We've find the smallest distance O(n) times.
- So, the running time is O(n^2 + m).
- Since m is O(n^2), the running time is O(n^2).
- That's a significant improvement over the previous algorithm.
- Can we improve it more? In particular, can we speed up the determination
of the smallest distance in Est?
- We might consider using a Heap, since we're doing a lot
of removeSmallest.
- However, we do change priorities of objects, and Heaps aren't
designed to easily support that operation. (How might you support
a
changePriority method?)
- We'll conclude our discussion of graphs by considering some other
common graph problems and some techniques for solving them.
- You'll note that most of our problems had to do with reachability
and minimization.
- We'll think about some variations.
Tuesday, 10 August 1999
- Created as a blank outline.
Monday, 6 December 1999
- Filled in Dijkstra's algorithm and remaining material.
Back to Shortest Path.
On to History of Computing (1).