Definition. Given a weighted graph G(V,E) and two nodes u,v in V, the
shortest paths between nodes u, v is a path whose total weight is minimum
among all possible such paths.
We can denote a shorest between u and v as d(u,v).
Note that we may have two different paths be shortest paths. Can
you think of
an example?
Theorem.1 (WHITE Theorem. 25.1)
A subpath P(u,v) of a shortest is a shortest path for u and v.
Proof. By contradiction.
Lemma.1 (WHITE Lemma. 25.3)
Given a weighted graph G(V,E) and a given node s, for all edges (u,v)
in E, the following
holds for the shortest paths:
d(s, v) <= d(s,u) + w(u,v)
Path Relaxation
------------
This refers to the procedure of improving our current estimate of the
weight of the
shortest path towards a particular node.
For a given source s, and and nodes u and v
Relax(s, v, u) {
// for (u,v) in E, else w(u,v) = + infinity
if D(s,v) > D(s, u) + w(u,v) //
if I have a better path through from s to v through u
D(s,v) = D(s,u) + w(u,v)
;
}
Note that D(u,v) here is my CURRENT best path from u to v.
We can build algorithms to find the shortest path by using the Path
Relaxation.
Dijkstra's Algorithm
----------------
Solves the single source shortest path problem for graphs with no negative
weights.
Note there are a lot of ways to implement Dijkstra. I present the one
I showed in the
class, and the use of black-grey-white coloring. This coloring is not
really necessary
but it helps at the visualization of the execution.
Dijkstra(G, s)
- Initialize: for all v in V, D[v] = + infinit
color[v] = white
parent[v] = NONE
- Initialize source: D[s] = 0
add s to queue Q // this is a priority queue
according to D[] value
color[s] = grey
- While Q not empty {
v = get-minimum-element from Q // remove it from Q
for all w, adjacent to v {
if color[w] == white {
add w in Q
color[w] = grey
}
// Path relaxation
if D(w) > D(v) + w(v,w) { // if I have a
better path through from s to w through u
D(w) = D(v) + w(v,w) ;
parent[w] = v ;
} // if
}
// for
color[v] = black;
} // while
Note that this is very similar with Prim's algorithm in
structure. What is the difference?
The way I calculate D[] changes. Here D[v] is the
minimum known distance
Why does Dikjstra has problems with negative weights? Show
an example.
The complexity of Dijkstra: one upper bound is O(N^2).
This is if I search every time my Q to find the minimum weight
element.
If I use more efficient priority queue then the complexity
can be O( (V+E) log V).
Bellman-Ford
-----------
It solves the single source shortest path problem.
It can work with negative weights for a directed graph, but not negative
cycles.
Bellman-Ford(G)
- Initialize: for all v in V, D[v] = + infinit
- Initialize source: D[s] = 0
- Repeat N-1 times
for each edge (u,v)
{
// Path relaxation
if D(v) > D(u) + w(u,v) { // if I have a
better path through from s to w through u
D(v) = D(u) + w(u,v) ;
parent[v] = u ;
} // if
}
The complexity of Bellman Ford is bounded above by O(N^3).
Explanation: We repeat O(N) and each repetition we visit all
the edges O(E).
So a more precise upper bound is O(N E).
If the edge representation is by adjacency matrix, then passing through
each edge
takes O(N^2), which gives the O(N^3) bound.