$ \def\opt{ {\mathrm{opt}} } \def\val{ {\mathrm{val}} } $
Bellman-Ford Algorithm for SSSP
Definition. For each $j = 0, 1, \ldots, n-1$ define $d_j(u, v) = $ length of shortest path from $u$ to $v$ consisting of $\leq j$ hops.
Observations.
Idea. Use second observation to compute $d_0(u, x), d_1(u, x), \ldots, d_{n-1}(u, x)$ for all $x$.
Bellman-Ford(V, E, w, u)
d <- 2d array [0..n-1, 1..n]
for v = 1 to n do d[0, v] <- infinity
d[0, u] <- 0
for j = 1 to n-1 do
for each vertex v in V set d[j, v] <- d[j-1,v]
for each vertex v in V
for each neighbor x of v
d[j, x] <- Min(d[j, x], d[j-1, v] + w[v, x])
return d[n-1]
Running time is $O(m n)$ if $G$ has $n$ vertices and $m$ edges.
Claim. For all $j = 0, 1, \ldots, n-1$ and for all vertices $v$, $d[j, v]$ stores length of shortest path from $u$ to $v$ with $j$ or fewer hops. I.e., $d[j, v] = d_j(v)$
Proof. Induction on $j$.
Base case, $j = 0$.
If $G$ has no negative weight cycles, then Bellman-Ford solves single source shortest paths in $O(m n)$ time.
Running times:
Why pick Bellman-Ford over Dijkstra?
Bellman-Ford(V, E, w, u)
d <- 2d array [0..n-1, 1..n]
for v = 1 to n do d[0, v] <- infinity
d[0, u] <- 0
for j = 1 to n-1 do
for each vertex v in V set d[j, v] <- d[j-1,v]
for each vertex v in V
for each neighbor x of v
d[j, x] <- Min(d[j, x], d[j-1, v] + w[v, x])
return d[n-1]
Modeling the network:
Question 1. How much material can the USSR transport to Western Europe per unit time?
Question 2. What is the cheapest way to disrupt flow of all material?
A new interpretation of directed graphs:
Question. How much fluid be routed from $s$ to $t$ per unit time?
Setup.
Flows. An s-t flow $f$ is a function $f : E \to \mathbf{R}^+$ satisfying:
The value of the flow $f$ is $\val(f) = \sum_{s \to v} f(s, v)$
Input.
Output.
Repeat until done:
Flow along $P$ may block other viable paths
Question. How to fix this?
Idea. Add “undo” feature for each edge
if $f$ routes $f(u, v) \leq c(u, v)$ flow from $u$ to $v$, add reverse edge $(v, u)$ with capacity $c(v, u) = f(u, v)$
using $(v, u)$ corresponds to “pushing back” flow from $(u, v)$
if an alternate route for this flow can be found, then more flow can be routed through $u$
Residual graph $G_f = (V_f, E_f)$
Very high level
We’ve found a path $P$ with minimum capacity $b > 0$!
Question. How do we…
MaxFlow(G, s, t):
Gf <- G
f <- zero flow
P <- FindPath(Gf, s, t)
while P is not null do:
b <- min capacity of any edge in P
Augment(Gf, f, P, b)
P <- FindPath(Gf, s, t)
endwhile
return f
Augment(Gf, f, P, b):
for each edge (u, v) in P
if (u, v) is forward edge then
f(u, v) <- f(u, v) + b
c(u, v) <- c(u, v) - b
c(v, u) <- c(v, u) + b
else
f(v, u) <- f(v, u) - b
c(v, u) <- c(v, u) + b
c(u, v) <- c(u, v) - b
Assume:
Observe:
How long to find augmenting path $P$?
How long to run Augment
?
How many iteraions of find/augment?
Conclude: Overall running time?
Ford-Fulkerson Correctness!