130 likes | 196 Views
Section 12: Graph Algorithms. Shortest Paths. Given a weighted graph, the shortest path between two vertices is the path between them whose edges have the lowest sum. Useful for: Finding cheap airline itineraries Finding fast airline itineraries Network routing
E N D
Shortest Paths • Given a weighted graph, the shortest path between two vertices is the path between them whose edges have the lowest sum.Useful for: • Finding cheap airline itineraries • Finding fast airline itineraries • Network routing • Much more -- often pops up unexpectedly
Shortest Path • Types of shortest path problems: • Single Pair: Given vertices v, w find the shortest path from v to w. • Single Source: Given a source vertex s, find the shortest paths from s to every other vertex. • All Pairs: Find the shortest paths between any two vertices. • Dijkstra’s Algorithm efficiently solves single source, which in turn solves single pair
Dijkstra’s Algorithm • The “standard” solution to the single-source problem is Dijkstra’s Algorithm. • Shortest paths are computed with a greedy algorithm: we repeatedly visit the nearest vertex we haven’t seen yet • Doesn’t work on disconnected graphs (e.g. if you can’t get from u to v, there is no shortest path) • Edge weights must be positive
d(s, s) = 0 < d(s, s1) = 5 < d(s, s2) = 6 < d(s, s3) = 8 < d(s, s4) = 15 Dijkstra’s Algorithm Suppose that the shortest distances from s to the other nodes are d(s, s) < d(s, s1) < d(s, s2) < … … < d(s, sn) A shortest path from s to si can’t possibly contain any sj with j > i. It can only use the vertices {s, s1, …, si-1}. Dijkstra’s Algorithm starts with s, then finds s1, then s2, and so on. s4 15 8 s3 2 10 s2 s 3 4 1 5 s1
Dijkstra’s Algorithm • Greedy selection rule: • Assume s, s1, s2, …, si-1 have already been selected, and their shortest distances have been stored • Select node si and save d(s, si)such that out of all nodes not yet selected, si has the shortest path to s using only nodes s, s1, …, si-1. • To do this efficiently, we need to track of the distance of the shortest path from s to v using only s, s1, …, si-1for each unselected v. Call this D[v].
Dijkstra’s Algorithm – Example Solution = {(s, 0)} D[s1] = 5 by path [s, s1] D[s2] = infinity by path [s, s2] D[s3] = 10 by path [s, s3] D[s4] = 15 by path [s, s4] Solution = {(s, 0),(s1, 5)} D[s2] = 6 by path [s, s1, s2] D[s3] = 9 by path [s, s1, s3] D[s4] = 15 by path [s, s4] Solution = {(s, 0),(s1, 5),(s2, 6)} D[s3] = 8 by path [s, s1, s2, s3] D[s4] = 15 by path [s, s4] Solution = {(s, 0),(s1, 5),(s2, 6),(s3, 8),(s4, 15)} s4 15 8 s3 2 10 s2 s 3 4 1 5 s1
Dijkstra’s Algorithm – updating D • Suppose we add some node near to the solution. How does this change D? • All nodes adjacent to near can now be reached through near – when does using near give us a shorter path?for all neighbors v of near not yet selected: if (D[near] + w(near, v) < D[v]) D[v] = D[near] + w(near, v);
Dijkstra’s Algorithm – Update Example Solution = {(s, 0)} D[s1] = 5, D[s2] = infinity, D[s3] = 10, D[s4] = 15 Solution = {(s, 0),(s1, 5)} D[s2] = D[s1] + w(s1, s2) = 5 + 1 = 6 D[s3] = D[s1] + w(s1, s3) = 5 + 4 = 9 D[s4] remains 15 Solution = {(s, 0),(s1, 5),(s2, 6)} D[s3] = D[s2] + w(s2, s3) = 6 + 2 = 8 D[s4] remains 15 Solution = {(s, 0),(s1, 5),(s2, 6),(s3, 8),(s4, 15)} s4 15 8 s3 2 10 s2 s 3 4 1 5 s1
Dijkstra’s Algorithm [For each vertex, we will store a “distance” field d and a “selected” field k. Initially, dv= infinity and kv = 0 for all v. Let s designate the source node.] Step 1: Set ds = 0. Step 2: for (i = 0; i < |V|; i++) { Out of all vertices with selected field = 0, choose the one with the lowest distance field. Call it x. kx = 1; for all neighbors y of x: if (dy > dx + w(x,y)) dy = dx + w(x,y); }
Dijkstra’s Algorithm • The tricky part is choosing the x with the lowest dx . We also have to subsequently update dy for all neighbors y of x.How can we do this efficiently? • Use an array to store the nodes • Use a heap to store the nodes, with the key being the distance field
Dijkstra’s Algorithm – Array • Store all of the vertices in an array. • Choosing the vertex with the smallest distance now requires searching the array; this takes time O(|V|). • Updating the distances takes only constant time for each edge. • Total running time is now O(|V|2 + |E|),which is really just O(|V|2). • This is good for dense graphs.
Dijkstra’s Algorithm – Heap • Store all of the vertices in a min-heap, where the key is the distance field. • Choosing the vertex with the smallest distance amounts to a deleteMin(); this takes time O(log |V|). • Updating the distances requires a call to decreaseKey() each time, and so takes time O(log |V|) for each edge. • Total running time is now O(|V| * log |V| + |E| * log |V|). • This is good for sparse graphs.