COS 423 Lecture 21
Maximum Flows
© Robert E. Tarjan 2011
Maximum Flow Problem
In a directed graph with source vertex s, sink
vertex t, and non-negative arc capaicities, find
a maximum flow from s to t.
Let G = (V, E) be a directed graph with source
vertex s, sink vertex t, arc capacities c(v, w) ≥ 0
Assume G is symmetric: (v, w) ∈ E iff (w, v) ∈ E
(Symmetrize by adding reverse arcs with
capacity 0 as necessary)
pseudoflow f: antisymmetric function on arcs
that is bounded by arc capacities:
f(v, w) = –f(w, v) ≤ c(v, w)
(antisymmetry simplifies some formulas)
excess e(v) of vertex v = Σ{f(u, v)|(u, v) ∈ E}
f is a preflow iff e(v) ≥ 0 for v ≠ s
f is a flow if e(v) = 0 for v ∉ {s, t}
value of f = e(t) (= –e(s) if f is a flow)
f is maximum if e(t) is maximum
Goal: find a maximum flow
A capacitated graph with a flow
(0-capacity symmetric arcs omitted)
a
100 100
50 50
s 1 0 t
50 50
100 100
b
Maximum flow
a
100 100
100 100
s 1 0 t
100 100
100 100
b
Bipartite matching via maximum flow
Find a matching of maximum size
a b c
d e f
Direct edges from X to Y, add source s sink t, arcs
from s to all v in S, arcs from all w in Y to t, all
capacities 1 s
a b c
d e f
t
Needs an integer solution
Augmenting path method
(Ford & Fulkerson)
(v, w) is saturated if f(v, w) = c(v, w), otherwise
residual
residual capacity of (v, w):
r(v, w) = c(v, w) – f(v, w)
augmenting path: path of residual arcs from s to
t
residual capacity of an augmenting path:
minimum residual capacity of arcs on path
f ← 0;
while ∃augmenting path P do
{Δ ← residual capacity of P;
for (v, w) on P do
{f(v, w) ← f(v, w) + Δ; f(w, v) ← f(w, v) – Δ}}
Augmenting path s, a, t
a
100 100
0 0
s 1 0 t
0 0
100 100
b
Augmenting path s, b, t
a
100 100
100 100
s 1 0 t
0 0
100 100
b
No augmenting path: flow is maximum
a
100 100
100 100
s 1 0 t
100 100
100 100
b
Correctness via duality
cut: a Partition of the vertices into two parts, X
containing s and Y containing t
capacity of cut:
c(X, Y) = Σ{c(x, y)|(x, y) ∈ E & x ∈ X & y ∈ Y}
net flow across cut:
f(X, Y) = Σ{f(x, y)|(x, y) ∈ E & x ∈ X & y ∈ Y}
≤ c(X, Y)
minimum cut: a cut of minimum capacity
Lemma: If X, Y is any cut and f is any flow, f(X, Y)
= e(t).
Proof: Exercise
Corollary: The maximum flow value is at most
the minimum cut capacity
Max Flow, Min Cut Theorem: The maximum flow
value equals the minimum cut capacity
Proof: Run the augmenting path algorithm until
there is no augmenting path. Let X be the set
of vertices reachable from s by a path of
residual arcs, Y the rest. Then y ∈ Y, so X, Y is a
cut. Also, if (x, y) ∈ E with x ∈ X & y ∈ Y, then
c(x, y) = f(x, y), so c(X, Y) = f(X, Y).
Termination?
Proof of max-flow, min-cut theorem requires
that the augmenting path algorithm
terminates.
Ford & Fulkerson: If arc capacities are integers,
each augmentation increases the flow value
by at least 1, so algorithm must terminate:
sum of arc capacities is an upper bound on
#augmentations. This argument extends to
fractional capacities. Also, if arc capacities are
integers, there is an integral maximum flow.
What if capacities are irrational?
How many augmentations?
Augmenting path s, a, b, t
a
100 100
0 0
s 1 0 t
0 0
100 100
b
Augmenting path s, b, a, t
a
100 100
1 0
s 1 1 t
0 1
100 100
b
Augmenting path s, b, a, t
a
100 100
1 1
s 1 0 t
1 1
100 100
b
Maximum flow after 198 more augmentations
#augmentations not polynomial in graph size
and #bits needed to represent capacities
If capacities are irrational, algorithm need not
terminate, flow value need not converge to
maximum (even though it will converge).
Efficiency requires a good choice of augmenting
paths
Edmonds &Karp: Choose augmenting path with
fewest arcs: O(nm) augmentations, O(nm2)
time.
Dinic: In each phase, find all augmenting paths
with k arcs but no fewer: reduces amortized
time per augmentation from O(m) to O(n),
total time to O(n2m) (just like Hopcroft-Karp
bipartite matching algorithm)
Faster, simpler algorithms
Break computation into smaller parts: change
flow on one arc at a time, move flow along
estimated shortest path to sink
Allow (temporary) excess flow at a vertex:
preflow (e(v) ≥ 0 for v ≠ s)
Vertex v ∉ {s, t} is active if e(v) > 0
valid vertex labeling d
d(v) is a non-negative integer,
d(t) = 0, d(s) = n,
d(v) ≤ d(w) + 1 if (v, w) is residual
→ d(v) is at most the number of arcs on a
residual path from v to t, if there is such a
path
Preflow push algorithm
d ← 0; d(s) ← n; f ← 0;
for (s, v) ∈ E do f(s, v) ← c(s, v);
while ∃ active v do
if ∃ residual (v, w) ∋ d(v) > d(w) then
f(v, w) ← f(v, w) + min{e(v), r(v, w)}
[push: saturating if it saturates (v, w), non-
saturating otherwise ]
else d(v) ← 1 + min{d(w)|(v, w) residual} [label]
After initialization: flows, labels
0
a
100 100
100 0
4 s 1 0 t 0
100 0
100 100
b
0
Process a: label, push to b
1
a
100 100
100 0
4 s 1 1 t 0
100 0
100 100
b
0
Process b: label, push to t
1
a
100 100
100 0
4 s 1 1 t 0
100 100
100 100
b
1
Process b: label, push to a
1
a
100 100
100 0
4 s 1 0 t 0
100 100
100 100
b
2
Process a: push to t, no active vertices
1
a
100 100
100 100
4 s 1 0 t 0
100 100
100 100
b
2
Basic properties of algorithm
After initialization, labeling is valid; while loop
maintains validity
f is always a preflow.
e(t) at any later time ≤ Σ Σ{e(v)|d(v) < n}
If e(v) > 0, there is a simple path of positive flow
from s to v (proof: exercise)
If e(v) > 0, d(v) < 2n – 1: there is a residual path
from v to s along which d can decrease by at
most 1 per arc
At most 2n – 1 labelings per vertex. Time to
label a vertex is O(degree). Time for all
labelings is O(nm).
Implementation of pushes: For each vertex v,
maintain a current arc (v, w). To process v in
while loop, do a push on current arc if
allowed; if not, replace current arc by next arc
on arc list; if current arc is last on list, label v
At most one saturating push per incident arc
between labelings of v → O(nm) saturating
pushes, O(1) time per push + O(nm) overhead
How many non-saturating pushes?
How to choose vertices for processing?
Variants
Label-tightening: Periodically, set all labels equal
to their maximum possible values (via BFS
backward from t followed by BFS backward
from s). Takes O(m) time
Lazy return of excess: do no steps at vertices of
label ≥n. Once done, return excess flow to s by
finding paths of positive flow from s to vertices
of label ≥n and reducing the flow on such paths.
Simple implementation takes O(nm) time
Running time by choice of vertices
Any order: O(n2m) time
Queue of active vertices(FIFO): O(n3) time
Highest label: O(n2m½) time
Large excess: O(n2lgU + nm) time, if capacities
are integers ≤U
Analysis: charge non-saturating pushes against
other steps via a potential function
Generic method
Φ = Σ{d(v)|v active}
0 ≤ Φ ≤ 2n2
A non-saturating push decreases Φ by at least
one → amortized cost ≤ 0
Amortized cost of a label of v = Δd(v)
Amortized cost of a saturating push ≤ 2n
→ #non-saturating pushes = O(n2m)
FIFO method
Define passes:
pass 0 = processing of initially active vertices
pass k + 1 = processing of vertices added to
queue during pass k
Φ = max{nd(v)|v active}
0 ≤ Φ ≤ 2n2
A pass does at most n non-saturating pushes, at
most one per vertex, has actual cost at most n
A pass that increases labels by a total of k
increases Φ by at most (k – 1)n → amortized
cost ≤ kn → total amortized cost ≤ 2n3
→ O(n3) running time
Large-excess method
Assume capacities are integral, at most U
Δ is a scale factor, initially the smallest power of
two no less than U
An excess is big if it is at least Δ/2
Process a vertex with big excess; break a tie in
favor of smallest label. Never allow an excess
to exceed Δ. When all active vertices have
small excess, divide Δ by 2
To maintain bound on excesses during a push:
increase f(v, w) by min{e(v), r(v, w), Δ – e(w)}
If e(v) is big, e(w) is not big, and the push is non-
saturating, then it increases e(w) by at least
Δ/2
Overhead to implement big-excess rule is O(nm)
A phase is the time between changes in Δ.
During the last phase, Δ = 1 → #phases ≤ lgU
Φ = Σ{2e(v)d(v)/Δ|v active}
0 ≤ Φ ≤ 4n2
Each non-saturating push decreases Φ by at
least 1 → amortized cost of a non-saturating
push is at most 0
Label increase of k increases Φ by at most 2k,
≤4n2 over all relabelings
Decrease in Δ doubles Φ, increasing Φ by at
most 2n2 per change in Δ, at most 2n2lgU over
all phases
→ O(n2lgU + nm) running time