Editing Dijkstra's algorithm

Jump to: navigation, search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 12: Line 12:
 
The preceding Lemma should give us an idea of how to proceed. We start with only the source vertex in the shortest-paths tree (<math>T</math> is merely the vertex set of the partial shortest-paths tree); its distance to itself is obviously zero. Then, we repeatedly apply the Lemma by considering all admissible paths and finding the shortest. To do this we consider all edges that lead from a <math>T</math> vertex <i>u</i> to a non-<math>T</math> vertex <i>v</i>. Concatenating the <i>s</i>-<i>u</i> shortest path and the <i>u</i>-<i>v</i> edge yields an admissible path whose length is the sum of the length of the already-known <i>s</i>-<i>u</i> path and the weight of the <i>u</i>-<i>v</i> edge. The edge and vertex <i>v</i> at the very end of the shortest admissible path are added to the shortest-paths tree (and thus <i>v</i> is added to <math>T</math>); as no path from <i>s</i> to a non-<math>T</math> vertex can be shorter, we are justified in claiming that <i>v</i> is the closest non-<math>T</math> vertex to <i>s</i>, and that its distance from <i>s</i> is the shortest obtainable from an admissible path currently. This method of extending the shortest-paths tree by one vertex is repeated until all vertices have been added, and induction proves the algorithm's validity. (The extension can always be performed because otherwise the remaining vertices would be unreachable from the source, a contradiction.)
 
The preceding Lemma should give us an idea of how to proceed. We start with only the source vertex in the shortest-paths tree (<math>T</math> is merely the vertex set of the partial shortest-paths tree); its distance to itself is obviously zero. Then, we repeatedly apply the Lemma by considering all admissible paths and finding the shortest. To do this we consider all edges that lead from a <math>T</math> vertex <i>u</i> to a non-<math>T</math> vertex <i>v</i>. Concatenating the <i>s</i>-<i>u</i> shortest path and the <i>u</i>-<i>v</i> edge yields an admissible path whose length is the sum of the length of the already-known <i>s</i>-<i>u</i> path and the weight of the <i>u</i>-<i>v</i> edge. The edge and vertex <i>v</i> at the very end of the shortest admissible path are added to the shortest-paths tree (and thus <i>v</i> is added to <math>T</math>); as no path from <i>s</i> to a non-<math>T</math> vertex can be shorter, we are justified in claiming that <i>v</i> is the closest non-<math>T</math> vertex to <i>s</i>, and that its distance from <i>s</i> is the shortest obtainable from an admissible path currently. This method of extending the shortest-paths tree by one vertex is repeated until all vertices have been added, and induction proves the algorithm's validity. (The extension can always be performed because otherwise the remaining vertices would be unreachable from the source, a contradiction.)
  
==Implementation 1==
+
==Implementation==
 
As the previous sections are a bit heavy, here is some pseudocode for Dijkstra's algorithm:
 
As the previous sections are a bit heavy, here is some pseudocode for Dijkstra's algorithm:
 
<pre>
 
<pre>
Line 26: Line 26:
 
           dist[w] = min(dist[w],dist[v]+wt(v,w))
 
           dist[w] = min(dist[w],dist[v]+wt(v,w))
 
</pre>
 
</pre>
Following the completion of this code, the <code>dist</code> array will contain the minimum path lengths from <code>s</code> to each vertex, or <math>\infty</math> if no such path exists for a given vertex.
 
 
===Analysis===
 
In each iteration the inner loop will add a vertex to <math>T</math>, so at most <math>V</math> iterations will take place; in each one it takes <math>O(V)</math> time to find the vertex with the minimal <code>dist</code> entry. The inner loop executes at most <math>2E</math> times, since it considers each edge at most twice (once from each endpoint). A naive implementation therefore takes <math>O(E+V^2)</math> time. In a dense graph, this is asymptotically optimal.
 
 
==Implementation 2==
 
This implementation allows us to make optimizations, and more closely follows the theory, but requires a data structure <code>Q</code>:
 
<pre>
 
input G,s
 
for each v ∈ V(G)
 
    let dist[v] = ∞
 
add (s,0) to Q
 
while Q is nonempty
 
    let (v,d) ∈ Q such that d is minimal
 
    remove (v,d) from Q
 
    if dist[v] = ∞
 
          dist[v] = d
 
          for each w ∈ V(G) such that (v,w) ∈ E(G)
 
              add (w,d+wt(v,w)) to Q
 
</pre>
 
Each iteration of the main loop is again an iteration of the Lemma. <math>T</math> is now implicit; it consists of all vertices with current distance (<code>dist</code> value) less than infinity. The data structure <code>Q</code> contains nodes that should potentially be explored next; it contains all nodes that are reachable from a single edge out of <math>T</math>. Selecting the closest one at each iteration, we eventually explore the entire connected component and compute all shortest paths.
 
 
===Analysis===
 
The data structure <code>Q</code> is a priority queue ADT. If we use the [[binary heap]] implementation, then insertion and removal both take <math>O(\log N)</math> time, whereas querying the minimal element takes constant time. At most <math>2E</math> edges are inserted and at most <math>V</math> deletions occur, which gives a time bound of <math>O((E+V) \log (2E))</math>. We assume the graph has no duplicate edges, so that <math>E < V^2</math>, and then <math>\log (2E) < 2 \log V + \log 2</math>, giving the oft-quoted <math>O((E+V) \log V)</math> time bound. Hence this implementation outperforms the first in a sparse graph, and running it once per vertex to obtain all-pairs shortest paths outperforms the [[Floyd–Warshall algorithm]] in sparse graphs.
 
 
Using a [[Fibonacci heap]] implementation, which supports amortized constant time insertion, we can improve this to <math>O(E + V \log V)</math>.
 
 
==Singly constrained variant==
 
Dijkstra's algorithm can solve the ''singly constrained shortest path problem''. In this problem, each edge has ''two'' nonnegative weights, a length and a cost, and we wish to minimize path length subject to the constraint that the total cost must not exceed <math>C</math>. The code looks very similar:
 
<pre>
 
input G,s
 
for each v ∈ V(G)
 
    let dist[v] = ∞
 
    let mincost[v] = ∞
 
add (s,0,0) to Q
 
while Q is nonempty
 
    let (v,d,c) ∈ Q such that c is minimal
 
    remove (v,d,c) from Q
 
    if d &lt; dist[v]
 
          dist[v] = d
 
          for each w ∈ V(G) such that (v,w) ∈ E(G) and c + cost(v,w) &le; C
 
              add (w,d+wt(v,w),c+cost(v,w)) to Q
 
</pre>
 
Following completion of this code, the <code>dist</code> array holds the minimum path lengths found, and the <code>mincost</code> array holds the cost, for each vertex, required to achieve the minimum distance.
 
  
 
==References==
 
==References==
Line 75: Line 31:
  
 
[[Category:Algorithms]]
 
[[Category:Algorithms]]
[[Category:Graph theory]]
 

Please note that all contributions to PEGWiki are considered to be released under the Attribution 3.0 Unported (see PEGWiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

Cancel | Editing help (opens in new window)