Let G=(V,E) be a directed graph and let P be a (possibly large) collection of paths through the graph.
A multicommodity flow f assigns a flow f(p) to each path p∈ P.
The size of the flow, |f|, is the total flow assigned: ∑_{p∈ P} f(p).
We let f(e) for any edge e denote the total flow sent across edge e: f(e) = ∑_{p∈ P, p∋ e} f(p).
The *congestion* of the flow, cong(f), is the maximum amount of
flow crossing any edge: max_{e∈ E} f(e).
Given a budget C, the goal is to find a flow of congestion at most C
maximizing the size of the flow.

Algorithm (given ε > 0):

1. Let f(p) = 0 for each p ∈ P. 2. Repeat until cong(f) = C : 3. Choose a path p ∈ P minimizing ∑_{e∈ p}(1+ε)^{f(e)}. 4. Let f(p) = f(p) + 1. (Send a unit of flow along P.) 5. Return f.

Note: in step 3, the path p can be found using a shortest path computations,
depending on the set of paths P. For example, if P contains all paths going
from s_{i} to t_{i} for some set of pairs of vertices {(s_{1},t_{1}), (s_{2},t_{2}), …, (s_{k}, t_{k})},
then the path can be found using k shortest path computations.

**thm:** *Assuming C ≥ \ln(m)/ε ^{2} and ε ≤ 1/2 the algorithm returns a flow of size at least (1-O(ε)) OPT.*

- Note if we could increase the congestion by at most C/|f*| in each iteration, we would converge to a minimum-congestion flow in about |f*| rounds. However, this is not possible (consider the first round, we increase congestion by 1 no matter what).
- Define φ(f) = ln
_{1+ε}∑_{e∈ E}(1+ε)^{f(e)}. Note that cong(f) ≤ φ(f). - φ is a "smooth" approximation of the congestion. The idea is that the algorithm chooses the path p in each iteration to (approximately) minimize the increase in φ (as a proxy for minimizing the increase in the congestion).
- Fix an iteration t. Let p denote the chosen path and let ψ(e) = (1+ε)
^{f(e)}at the start of the iteration. Then, using log_{1+ε}(1+z) ≤ (1+O(ε))z for ε < 1/2,- φ(f
_{t}) - φ(f_{t-1}) = ln_{1+ε}[ 1 + ε ∑_{e∈ p}ψ(e) / ∑_{e}ψ(e)] ≤ [1+O(ε)] ∑_{e∈ p}ψ(e) / ∑_{e}ψ(e).

- φ(f

- Let f* be a maximum size flow of congestion at most C. Define a probability distribution Pr on the paths by Pr(p) = f*(p)/|f*|. If we choose a path p at random according to this probability distribution, and send 1 unit of flow along p, then the probability that a given edge e is on p is ∑
_{p∋ e}f*(p)/|f*| ≤ C/|f*|. Thus, if we were to choose a random path p during an iteration, φ would increase in expectation by at most [1+O(ε)] C/|f*|]. - Since the algorithm chooses p to minimize the increase in φ with each iteration, φ(f) increases by at most [1+O(ε)]] C/|f*|] each iteration. Thus, the algorithm maintains the invariant:
- φ(f) ≤ O(ln(m)/ε) + [1+O(ε)] C |f|/|f*|].

- At the end, φ(f) ≥ C (because cong(f)≤ φ(f)) so
- C ≤ O(ln(m)/ε) + [1+O(ε)] C |f|/|f*|].

- Rewriting and using 1/[1+O(ε)] = 1-O(ε) for ε < 1/2,
- |f|/|f*| ≥ 1-O(ε) - O(ln(m)/(ε C)).

References: