Topological Sorting and Least-cost Path Algorithms Topological Sort ● Topological sort of a dag G = (V, E) ■ Linear ordering A of all vertices from V ■ If edge (u,v) E => A[u] < A[v] undershorts socks watch pants shoes shirt belt tie jacket socks, undershorts, pants, shoes, watch, shirt, belt, tie, jacket |V| |V| But this is O( |V|2 ) Topological Sort ● Uses DFS ● Topological-Sort (G) ■ Call DFS (G) to compute finishing times f[v] for each v ■ Output vertices in decreasing order of finishing time ● Time complexity ■ O (|V| + |E|) Example 11, 16 undershorts socks 17, 18 watch 12, 15 pants 6, 7 shoes shirt 1, 8 tie 2, 5 jacket 3, 4 13, 14 belt 18-socks, 16-undershorts, 15-pants, 14-shoes, 10-watch, 8-shirt, 7-belt, 5-tie, 4-jacket 9, 10 Correctness ● Theorem ■ Topological-Sort(G) produces a topological sort of a directed acyclic graph G ● Proof: ■ Consider any edge (u, v) ○ Suffices to show f[v] < f[u] ■ Three possible types of edges ○ Tree edge, forward edge, cross edge Single-Source Shortest Path ● Problem: given a weighted directed graph G, find the minimum-cost path from a given source vertex s to every other vertex v ■ “Shortest-path” = minimum weight ■ Weight of path is sum of edges ■ E.g., a road map: what is the shortest path from Millersville to Wrightsville? Dijkstra’s Algorithm ● Cannot have negative edge weights ● Similar to breadth-first search ■ Grow a tree gradually, advancing from vertices taken from a queue (priority queue instead of normal queue) ● Also similar to Prim’s algorithm for MST ■ Use a priority queue keyed on d[v] B 2 10 A 4 5 What will be the total running time? D 3 C 1 Dijkstra’s Algorithm Dijkstra(G) B 2 10 for each v V 4 3 A D d[v] = ; d[s] = 0; S = ; Q = V; 5 1 C while (Q ) u = ExtractMin(Q); S = S U {u}; for each v u->Adj[] if (d[v] > d[u]+w(u,v)) Relaxation d[v] = d[u]+w(u,v); Step Note: this p[v] = u; is really a call to Q->DecreaseKey() for a priority queue Q Dijkstra’s Algorithm Dijkstra(G) for each v V d[v] = ; d[s] = 0; S = ; Q = V; while (Q ) HowO(V many lg V)times is u = ExtractMin(Q); ExtractMin() called? S = S U {u}; for each v u->Adj[] HowO(E many lg V)times is if (d[v] > d[u]+w(u,v)) DecreaseKey() d[v] = d[u]+w(u,v); called? p[v] = u; What will total running O(E lg V +beV the lg V) = O(E lg V) time? since E <= V2 Relaxation ● Key operation: relaxation ● Let (u,v) be cost of shortest path from u to v ■ Maintain upper bound d[v] on (s,v): Relax(u,v,w) { if (d[v] > d[u]+w) then { d[v]=d[u]+w; p[v] = u; } } } w w 5 2 u 5 u Relax 2 9 5 v u 7 5 v u 2 6 Relax 2 v 6 v Bellman-Ford Algorithm BellmanFord() for each v V d[v] = ; d[s] = 0; for i=1 to |V|-1 { for each edge (u,v) E Relax(u,v, w(u,v)); } for each edge (u,v) E if (d[v] > d[u] + w(u,v)) return “no solution”; Initialize d[], which will converge to shortest-path value Relaxation: Make |V|-1 passes, relaxing each edge Test for solution: have we converged yet? Ie, negative cycle? Relax(u,v,w): if (d[v] > d[u]+w) then d[v]=d[u]+w Bellman-Ford Algorithm BellmanFord() for each v V d[v] = ; d[s] = 0; for i=1 to |V|-1 for each edge (u,v) E Relax(u,v, w(u,v)); for each edge (u,v) E if (d[v] > d[u] + w(u,v)) return “no solution”; What will be the running time? Relax(u,v,w): if (d[v] > d[u]+w) then d[v]=d[u]+w Bellman-Ford ● Running time: O(VE) ■ Not so good for large dense graphs ■ But a very practical algorithm in many ways ● Note that order in which edges are processed affects how quickly it converges ● A distributed variant of the Bellman–Ford algorithm is used in distance-vector routing protocols