Go Back

Topics

Dijkstra's Algorithm

Statement

Consider a digraph D = (N, A) with non-negative weights w ∈ ℝ≥0A and a node s. Dijkstra's algorithm finds a tree of shortest dipaths rooted from s. We assume all nodes are reachable from s.

Pseudocode

Dijkstra(D = (N, A), w ∈ ℝ≥0A, s ∈ N)
1:   for all u ∈ N do
2:       y(u) := ∞
3:       p(u) := undefined
4:   end for
5:   y(s) := 0
6:   Q := N   // Set of unfinalized nodes
7:   while Q ≠ ∅ do
8:       u := argmin{ y(v) : v ∈ Q }
9:       remove u from Q
10:      for all arcs (u, v) ∈ A do
11:          if y(v) > y(u) + wuv then
12:              y(v) := y(u) + wuv
13:              p(v) := u
14:          end if
15:      end for
16:  end while
17:  return (y, p)
    

Correctness

Dijkstra's algorithm is correct under the assumption that w(e) ≥ 0 for all e ∈ A. When a node u is selected (finalized) at line 8, y(u) is the length of the shortest s-u dipath.

Note: The algorithm fails if negative arc weights are allowed.

Time Complexity

Topological Ordering and Shortest Paths in Acyclic Graphs

Topological Ordering

Let D = (N, A) be a directed acyclic graph (DAG). A topological ordering of D is a bijection π : N → {1, ..., |N|} such that for every arc (u, v) ∈ A, π(u) < π(v).
That is, every node comes before all its out-neighbors in the ordering.

Algorithm: Finding a Topological Order

Topological-Order(D = (N, A))
1:  L := empty list (will contain the order)
2:  S := { u ∈ N : u has in-degree 0 }
3:  while S ≠ ∅ do
4:      remove a node u from S
5:      append u to L
6:      for each (u, v) ∈ A do
7:          remove arc (u, v) from A
8:          if v now has in-degree 0 then
9:              insert v into S
10:     end for
11: end while
12: if any arcs remain in A then
13:     return "Graph has a cycle"
14: else
15:     return L
    

Shortest Path Algorithm for Acyclic Graphs (DAGs)

If D = (N, A) is a DAG with weights w ∈ ℝA, and s ∈ N is a source, we can compute shortest paths from s to all nodes in O(|N| + |A|) time.

Acyclic-Shortest-Paths(D = (N, A), w ∈ ℝA, s ∈ N)
1:  Compute a topological order π of D
2:  for all u ∈ N do
3:      y(u) := ∞
4:      p(u) := undefined
5:  end for
6:  y(s) := 0
7:  for k = 1 to |N| do
8:      u := node with π(u) = k
9:      for all (u, v) ∈ A do
10:         if y(v) > y(u) + wuv then
11:             y(v) := y(u) + wuv
12:             p(v) := u
13:         end if
14:     end for
15: end for
16: return (y, p)
    

Correctness

Remark: The acyclic shortest path algorithm works for any weights (even negative), provided the graph is acyclic.

Dantzig's Algorithm

Statement

Let D = (N, A) be a directed graph with arc weights w ∈ ℝA and a source node s ∈ N. Dantzig's algorithm computes shortest path distances from s to all other nodes, as long as there are no negative-weight dicycles in D.

Pseudocode

Dantzig(D = (N, A), w ∈ ℝA, s ∈ N)
1:  for all u ∈ N do
2:      y(u) := ∞
3:      p(u) := undefined
4:  end for
5:  y(s) := 0
6:  Q := {s}   // Set of nodes to process
7:  while Q ≠ ∅ do
8:      remove a node u from Q
9:      for all (u, v) ∈ A do
10:         if y(v) > y(u) + wuv then
11:             y(v) := y(u) + wuv
12:             p(v) := u
13:             if v ∉ Q then
14:                 add v to Q
15:             end if
16:         end if
17:     end for
18: end while
19: if any label y(v) was updated more than |N| - 1 times then
20:     return "Graph contains a negative-weight dicycle"
21: else
22:     return (y, p)
    

Explanation

Correctness

Remark: Dantzig's algorithm is a generic label-correcting method; special cases include the Bellman-Ford and queue-based SPFA algorithms.

Time Complexity

Bellman-Ford Algorithm and Finding Negative Dicycles

Statement

Let D = (N, A) be a directed graph with arc weights w ∈ ℝA and a source node s ∈ N. The Bellman-Ford algorithm computes the shortest path distances from s to every node. The algorithm detects the existence of negative-weight dicycles (directed cycles) if present.

Notation

Pseudocode

Bellman-Ford(D = (N, A), w ∈ ℝA, s ∈ N)
1:  y(0)(s) := 0
2:  y(0)(u) := ∞ for all u ∈ N, u ≠ s
3:  p(u) := undefined for all u ∈ N
4:  for i = 1 to |N| - 1 do
5:      for all v ∈ N (in any order) do
6:          y(i)(v) := min { y(i-1)(v), min(u,v)∈A [ y(i-1)(u) + wuv ] }
7:          if y(i)(v) < y(i-1)(v) then
8:              Let u ∈ N such that y(i)(v) = y(i-1)(u) + wuv
9:              p(v) := u
10:         end if
11:     end for
12: end for
13: for all (u, v) ∈ A do
14:     if y(|N|-1)(v) > y(|N|-1)(u) + wuv then
15:         return "D contains a negative-weight dicycle"
16:     end if
17: end for
18: return (y(|N|-1), p)
    

Finding a Negative Dicycle (if exists)

Find-Negative-Dicycle(p, v)
1:  Mark all nodes as unvisited
2:  for i = 1 to |N| do
3:      v := p(v)
4:  end for
5:  start := v
6:  C := [start]
7:  v := p(start)
8:  while v ≠ start do
9:      Append v to C
10:     v := p(v)
11: end while
12: return C   // C is the negative-weight dicycle
    

Correctness

Time Complexity