A graph is a set of vertices and a set of edges $G = (V,E)$ with a weight function $w : E \rightarrow \mathbb{R}$ mapping edges to weights.
The weight of a path, $w(p)$, is a sum of the weights of edges on this path
$$
w(p) = \sum_{i = 1}^{k} w(v_{i - 1},v_{i})
$$
And we define the shortest path, $\delta(u,v)$, to be
$$
\delta(u,v) =
\begin{cases}
min\{w(p) : u \rightarrow v\} & path(u,v)\\
\infty & else
\end{cases}
$$
General About Shortest Path Finding
Shortest path from start point to all destinations.
Oriented, weighted graphs.
The problem has optimal substructure:
Assume $x \rightarrow y \rightarrow z$ shortest path.
Assume that $w(y_1 \rightarrow z_1)$ is less than $(y \rightarrow z)$.
Now replace $y \rightarrow z$ with $y_1 \rightarrow z_1$ to obtain a contradiction to the assumption that $x \rightarrow y \rightarrow z$ is a shortest path.
For cycles in graphs we have that if two rounds results in a weight less than that of one round, we can loop for ever to reduce weight, thus obtaining a shortest path weight of $-\infty$.
Relaxing is a common method used within shortest path algorithms. Before we can relax a graph, we iterate the graph adding for each vertex, $v$, the attributes $v.d$ and $v.\pi$, that is shortest path estimate and predecessor, respectively. For this we have
Init-Single-Source(G,s)
for each vertex v \in G.V
v.d = ∞
v.π = Nil
s.d = 0
And the Relax pseudo code is:
Relax(u,v,w)
if v.d > u.d + w(u,v)
v.d = u.d + w(u,v)
v.π = u
The idea is very simple. If a vertex has a larger estimate than the weight of the current edge, update estimate.
Shortest Path Properties
Triangle inequality For any edge $(u,v) \in E$ we have that $\delta(s,v) \leq \delta(s,u) + w(u,v)$.
Upper-bound property We always have $v.d \geq \delta(s,v)$ for alle vertices $v \in V$, and once $v.d$ achieves the value $\delta(s,v)$, it never changed.
No-path property If there is no path from $s$ to $v$, then we always have $v.d = \delta(s,v) = \infty$.
Convergence property If $s \rightsquigarrow u \rightarrow v$ is a shortest path in $G$ for some $u,v \in V$, and if $u.d = \delta(s,u)$ at any time prior to relaxing edge $(u,v)$, then $v.d = \delta(s,v)$ at all times afterwards.
Path-relaxation property If $p = \langle v_0, v_1, ..., v_k \rangle$ is a shortest path from $s = v_0$ to $v_k$ and we relax the edges of $p$ in the order $(v_0,v_1),(v_1,v_2),...,(v_{k - 1},v_k)$, then $v_k.d = \delta(s,v_k)$. This property holds regardless of any other relaxation steps that occur, even if they are intermixed with relaxations of the edges of $p$.
Predcessor-subgraph property Once $v.d = \delta(s,v)$ for all $v \in V$, the predecessor subgraph is a shortest-path tree rooted at $s$.
Dijkstra's Algorithm
The algorithm can't handle negative edges. The algorithm can be implemented very efficiently using a min-heap. The idea is quite simple. Let $S$ some structure to store final shortest paths in. Let $Q$ be a min-priority heap with vertices. We get
Dijkstra(G,w,s)
S = \emptyset
Q = Heap
while Q \neq \emptyset
u = ExtractMin(Q)
S = S \union {u}
for each vertex v \in G.Adj[u]
Relax(u,v,w)
Example
Corectness of Dijkstra's Alg
The proof rely on the shortest path properties. We show by loop invariant that when a vertex estimate, $v$, is added to $S$, then we have that $v.d = \delta(s,v)$. In general $s$ is the very first vertex added to $S$.
By initialization we have that $S = \emptyset$ which is trivially true.
Maintenance. We wish to show that in each iteration $u.d = \delta(s,u)$ for the vertex added to $S$. For the purpose of contradiction assume that $u$ is the first vertex added to $S$ where $u.d \neq \delta(s,u)$. We get
$u \neq s$ since $s$ is the first vertex added to $S$, and $s.d = \delta(s,s) = 0$.
By the above we have that $S \neq \emptyset$ just before $u$ is added to $S$.
There must be some path from $s$ to $u$, otherwise $u.d = \delta(s,u) = \infty$ by no-path prop. which violates the assumption that $u.d \neq \delta(s,u)$.
Since there is at least one path, there is a shortest path, $p$, from $s$ to $u$.
Prior to adding $u$ to $S$, path $p$ connects a vertex in $S$, $s$, to a vertex in $S - V$, $u$.
Consider the first vertex $y$ along $p$ such that $y \in V - S$.
Let $x \in S$ be $y$'s predecessor along $p$.
We can decompose path $p$ into $s \rightsquigarrow x \rightarrow y \rightsquigarrow u$.
We claim that $y.d = \delta(s,y)$ when $u$ is added to $S$. Proof: Observe that $x \in S$. Since $u$ is the first vertex added where $u.d \neq \delta(s,u)$, we have that $x.d = \delta(s,x)$ when $x$ was added to $S$. Edge $(x,y)$ was relaxed at that time, and we conclude using the convergence property.
Contradiction is now obtained.
Since $y$ appears before $u$ on a shortest path from $s$ to $u$ and all edge weights are non-negative, we have $\delta(s,y) \leq \delta(s,u)$ and thus $y.d = \delta(s,y) \leq \delta(s,u) \leq u.d$ (upper bound prop).
But we also have that $y$ and $u$ were in $V - S$ when $u$ was chosen: we have that $u.d \leq y.d$ and thus the equality $y.d = u.d$.
Finally we have that $u.d = \delta(s,u)$ which is absurd compared to our original assumption.
Termination. At termination we have that $Q = \emptyset$ which along with earlier invariants that $Q = V - S$ implies that $S = V$.
By all this we have that Dijkstra's alg results in a set, $S$, of shortest paths.
Running time
Implemented with a min priority heap we have a time complexity of $O((V + E) lg V) = O(E \cdot lg V)$. That is: we iterate $E$ times, and for each iteration we do a decrease key that takes time $O(lg V)$. We can optimize this a bit by using a fib-heap. In this case we get $O(V \cdot lg V + E)$.
Bellman/Ford alg
This algoright can detect and report negative cycles. The code is
Bellman-Ford(G,w,s)
Init-Single-Source(G,s)
for i = 1 to |G.V| - 1
for each edge (u,v) \in G.E
Relax(u,v,w)
for each edge (u,v) \in G.E
if v.d > u.d + w(u,v)
return False
return True
Running Time of Bellman/Ford
init-single-source is $O(V)$. The first for-loop executes $O(V)$ times, which for each there is a inner loop that executes $O(E)$ times. In total we get $O(E \cdot V)$.
CommentsGuest Name:Comment:
[Neural_Networks] The XOR problem as a Neural Network;;Default.aspx?id=21;;;;[Neural_Networks] Sigmoid Neurons;;Default.aspx?id=19;;;;[Neural_Networks] Perceptrons;;Default.aspx?id=18;;;;[Parallel_Programming] Functions for Array Manipulation;;Default.aspx?id=20;;;;[Natural_Language_Processing] Basic N-Gram Model in Python;;Default.aspx?id=17;;;;[Program_Synthesis] Auto Complete;;Default.aspx?id=16;;;;[Program_Synthesis] Sketching;;Default.aspx?id=15;;;;[Lambda_Calculus] Church Numerals;;Default.aspx?id=14;;;;[Lambda_Calculus] Church Pairs;;Default.aspx?id=13;;;;[Lambda_Calculus] Church Booleans;;Default.aspx?id=12;;;;[Computer_Systems] Virtual Memory #2;;Default.aspx?id=11;;;;[Computer_Systems] Virtual Memory #1;;Default.aspx?id=1;;;;[Computer_Systems] Race Conditions;;Default.aspx?id=3;;;;[Computer_Systems] Semaphores;;Default.aspx?id=2;;;;[Algorithms_and_Datastructures] Shortest Path;;Default.aspx?id=10;;;;[Algorithms_and_Datastructures] Minimum Spanning Trees;;Default.aspx?id=9;;;;[Algorithms_and_Datastructures] Binary Search Trees;;Default.aspx?id=8;;;;[Algorithms_and_Datastructures] Heaps;;Default.aspx?id=7;;;;[Algorithms_and_Datastructures] Huffmann Codes;;Default.aspx?id=6;;;;[Algorithms_and_Datastructures] LCS - Longest Common Subsequence;;Default.aspx?id=5;;;;[Algorithms_and_Datastructures] MergeSort;;Default.aspx?id=4;;;;