Tutorials › Graph Theory (Undergraduate) › Capacity Planning With Flow Networks

Applications of Graph Theory · Tutorial 790 of 799

Capacity Planning With Flow Networks

Model a supply system as a capacitated directed graph, calculate feasible deliveries, and certify the maximum throughput with a minimum cut.

Intermediate 11 min read

What You'll Learn

  • Define a capacitated network with a source, a sink, and flow-conservation rules.
  • Calculate a feasible flow and check its value at every intermediate vertex.
  • Use a cut to bound the amount any network can deliver.
  • Trace augmenting paths, including a path that reverses an earlier routing choice.
  • Identify a minimum cut and interpret its capacity as a throughput bottleneck.

From Supply Limits to a Flow Network

A supply network may have several stages: material leaves a depot, passes through intermediate facilities, and reaches a destination. Each connection has a limit on how much can pass through it. A graph model makes it possible to distinguish two questions: can a proposed delivery plan be carried out, and what is the largest delivery the network can support? The first is checked by capacities and conservation; the second can be certified by comparing a flow with a cut.

Throughout, a network is a finite directed graph with a nonnegative capacity on each arc, a designated source \(s\), and a distinct sink \(t\). For simplicity, assume there are no arcs entering \(s\), no arcs leaving \(t\), and no pair of opposite arcs. Capacities are upper limits, not required amounts. A flow can leave unused capacity. The examples use whole-number capacities; the maximum-flow algorithm proved below assumes all capacities are integers.

Definition: A flow assigns a number \(f(u,v)\) to each directed arc \(uv\), with \(0\le f(u,v)\le c(u,v)\), where \(c(u,v)\) is its capacity. At every vertex \(v\) other than \(s\) and \(t\), flow is conserved: the total flow entering \(v\) equals the total flow leaving \(v\). The value \(|f|\) is the total flow leaving \(s\). A flow is feasible if it satisfies all capacity bounds and conservation equations.

A directed \(s\)-\(t\) cut is specified by a set \(S\subseteq V\) with \(s\in S\) and \(t\notin S\). Its capacity is the sum of the capacities of arcs directed from \(S\) to \(V\setminus S\). Arcs directed into \(S\) are not included. A minimum cut is an \(s\)-\(t\) cut of least capacity. Its outgoing arcs indicate a collection of connections that collectively limits delivery.

Why Cuts Bound Every Delivery

Proposition: In a finite directed network as specified above, the value of any feasible flow is at most the capacity of every \(s\)-\(t\) cut.

Proof. Fix a feasible flow \(f\) and a cut \(S\). Sum, over all vertices in \(S\), the amount of flow leaving each vertex minus the amount entering it. For every vertex in \(S\setminus\{s\}\), this difference is zero by conservation. At \(s\), it is \(|f|\), since no arc enters \(s\). In the sum, flows on arcs whose two endpoints are both in \(S\) cancel: each is counted once as leaving and once as entering. The remaining expression is the flow on arcs directed from \(S\) to \(V\setminus S\), minus the flow on arcs directed from \(V\setminus S\) into \(S\). Thus $$ |f|=\sum_{\substack{uv:\ u\in S\\v\notin S}} f(u,v) -\sum_{\substack{uv:\ u\notin S\\v\in S}} f(u,v). $$ The second sum is nonnegative, and each term in the first sum is at most its arc's capacity. Therefore $$ |f|\le \sum_{\substack{uv:\ u\in S\\v\notin S}} c(u,v), $$ which is the cut capacity. \(\square\)

This proposition gives an upper bound, but it does not by itself show that the bound can be attained. When a feasible flow and a cut have equal value and capacity, respectively, the proposition certifies both that the flow is maximum and that the cut is minimum.

Worked Example: Delivering Supplies Through Two Facilities

Let \(V=\{s,a,b,t\}\), with directed arcs \(sa,sb,ab,at,bt\). Their capacities are \(c(sa)=4\), \(c(sb)=3\), \(c(ab)=2\), \(c(at)=2\), and \(c(bt)=3\). Find a feasible delivery plan and certify the maximum amount.

Send 2 units along \(s\to a\to t\), and 3 units along \(s\to b\to t\). The resulting arc flows are \(f(sa)=2\), \(f(sb)=3\), \(f(ab)=0\), \(f(at)=2\), and \(f(bt)=3\). Each is within capacity: \(2\le4\), \(3\le3\), \(0\le2\), \(2\le2\), and \(3\le3\).

At \(a\), 2 units enter and \(2+0=2\) units leave. At \(b\), 3 units enter from \(s\), no units enter from \(a\), and 3 units leave for \(t\). So conservation holds at both intermediate vertices, and the flow value is \(2+3=5\).

Take \(S=\{s,a,b\}\). The only arcs from \(S\) to \(V\setminus S=\{t\}\) are \(at\) and \(bt\), so the cut capacity is \(2+3=5\). The feasible flow has value 5, equal to this cut capacity. The proposition shows no flow can have value greater than 5; hence the maximum deliverable amount is 5, and this cut is minimum. The source connections have total capacity \(4+3=7\), but the two final connections together allow only 5 units through.

Check: the source sends \(2+3=5\) units, and the sink receives \(2+3=5\) units. The flow and cut give the same value, so the upper bound is attained.

Finding a Maximum Flow by Augmenting Paths

To find a flow systematically, keep track of residual possibilities. If an arc \(uv\) has capacity \(c(u,v)\) and currently carries \(f(u,v)\), its forward residual capacity is \(c(u,v)-f(u,v)\). There is also a reverse residual move \(vu\) of capacity \(f(u,v)\): using it cancels some flow previously sent along \(uv\). A residual \(s\)-\(t\) path is a sequence of such positive-capacity moves from \(s\) to \(t\). Augmenting along it means increasing flow on forward moves and decreasing flow on reverse moves by the same amount, namely the smallest residual capacity on the path.

Theorem (integer-capacity maximum-flow minimum-cut): In a finite network with integer capacities and the assumptions stated above, repeatedly augmenting along any available residual \(s\)-\(t\) path eventually produces a maximum flow. When no such path remains, the set of vertices reachable from \(s\) by positive-capacity residual moves defines a minimum cut whose capacity equals the flow value.

Proof. Start with zero flow, which satisfies every capacity bound and conservation equation. At any stage, choose a residual \(s\)-\(t\) path and let \(\Delta\) be the least residual capacity on it. Increase flow by \(\Delta\) on each forward move and decrease it by \(\Delta\) on each reverse move. Since \(\Delta\) does not exceed any residual capacity, the updated flow stays within all original capacity bounds. At each internal vertex of the path, one unit of the update enters and one leaves; therefore conservation is preserved. The flow value increases by \(\Delta\). All capacities and flows remain integers, so \(\Delta\) is a positive integer. The flow value is bounded above by the total capacity of arcs leaving \(s\); consequently, only finitely many augmentations can occur.

When the algorithm stops, let \(S\) consist of \(s\) and every vertex reachable from \(s\) by positive-capacity residual moves. There is no residual path to \(t\), so \(t\notin S\). Any original arc \(uv\) directed from \(S\) to \(V\setminus S\) must be saturated: if \(f(u,v)<c(u,v)\), its forward residual move would reach \(v\). Any original arc \(vu\) directed from \(V\setminus S\) into \(S\) must carry zero flow: if \(f(v,u)>0\), its reverse residual move from \(u\in S\) to \(v\notin S\) would reach \(v\). Apply the cut identity in the proposition. The flow on outgoing cut arcs equals their total capacity, and the incoming cut arcs carry zero flow. Hence the flow value equals the capacity of this cut. The proposition says every feasible flow is at most every cut capacity, so this flow is maximum and this cut is minimum. \(\square\)

Worked Example: Reversing an Earlier Routing Choice

Let \(V=\{s,a,b,c,d,t\}\) and let the directed arcs be \(sa,sb,ac,ad,bc,ct,dt\), each of capacity 1. Trace the augmenting-path method and find a maximum flow.

Initially every arc has 1 unit of forward residual capacity. Use breadth-first search, exploring neighbors in the order shown by the vertex labels in the table. The queue records vertices waiting to be processed.

SearchVertex processedNewly reached verticesQueue afterwards
First\(s\)\(a,b\)\([a,b]\)
First\(a\)\(c,d\)\([b,c,d]\)
First\(b\)None; \(c\) is already reached\([c,d]\)
First\(c\)\(t\)\([d,t]\)

The first path found is \(s\to a\to c\to t\), with residual capacities \(1,1,1\). Its bottleneck is \(\min(1,1,1)=1\), so send 1 unit along it. Now \(sa,ac,ct\) are saturated. The reverse residual move \(c\to a\) has capacity 1 because the flow on \(ac\) is 1.

Search again in the updated residual network:

SearchVertex processedNewly reached vertexQueue afterwards
Second\(s\)\(b\)\([b]\)
Second\(b\)\(c\)\([c]\)
Second\(c\)\(a\), by the reverse move \(c\to a\)\([a]\)
Second\(a\)\(d\)\([d]\)
Second\(d\)\(t\)\([t]\)

The second residual path is \(s\to b\to c\to a\to d\to t\). Its residual capacities are all 1, including the reverse move \(c\to a\), so its bottleneck is 1. Augment by 1: send flow on \(sb,bc,ad,dt\), and cancel the 1 unit previously sent on \(ac\). The final flows are \(f(sa)=1\), \(f(sb)=1\), \(f(ac)=0\), \(f(ad)=1\), \(f(bc)=1\), \(f(ct)=1\), and \(f(dt)=1\).

At \(a\), 1 unit enters on \(sa\) and 1 leaves on \(ad\). At \(b\), 1 enters on \(sb\) and 1 leaves on \(bc\). At \(c\), 1 enters on \(bc\) and 1 leaves on \(ct\). At \(d\), 1 enters on \(ad\) and 1 leaves on \(dt\). Thus conservation holds, and the flow value is \(1+1=2\). The cut \(S=\{s\}\) has capacity \(c(sa)+c(sb)=1+1=2\). Equality certifies that the flow is maximum. The reverse move mattered: it withdrew flow from \(ac\) so that \(a\)'s supply could instead reach \(t\) through \(ad\).

Reading the Bottleneck in a Capacity Plan

Worked Example: An Internal Cut Limits Throughput

Let \(V=\{s,a,b,t\}\), with arcs \(sa,sb,ab,at,bt\) of capacities \(8,4,3,2,7\), respectively. Determine the maximum flow and locate a minimum cut.

Send 5 units on \(sa\), then split them: send 2 on \(at\) and 3 on \(ab\). Send 4 units on \(sb\), and send the resulting 7 units leaving \(b\) on \(bt\). In arc order \(sa,sb,ab,at,bt\), the flows are \(5,4,3,2,7\); the corresponding capacity checks are \(5\le8\), \(4\le4\), \(3\le3\), \(2\le2\), and \(7\le7\). At \(a\), \(5=3+2\), and at \(b\), \(4+3=7\), so conservation holds. The flow value is \(5+4=9\).

To check the possible cuts, a set \(S\) must contain \(s\) and exclude \(t\); here the only choices are \(\{s\}\), \(\{s,a\}\), \(\{s,b\}\), and \(\{s,a,b\}\). Their capacities are, respectively:

  • \(\{s\}\): \(c(sa)+c(sb)=8+4=12\).
  • \(\{s,a\}\): \(c(sb)+c(ab)+c(at)=4+3+2=9\).
  • \(\{s,b\}\): \(c(sa)+c(bt)=8+7=15\).
  • \(\{s,a,b\}\): \(c(at)+c(bt)=2+7=9\).

The least cut capacity is 9, attained by \(\{s,a\}\) and \(\{s,a,b\}\). Since the feasible flow has value 9, it is maximum. In the cut \(\{s,a\}\), the outgoing arcs are \(sb,ab,at\), with total capacity \(4+3+2=9\). These connections form a bottleneck: the source has 12 units of outgoing capacity, but no plan can deliver more than 9 units across this cut.

Check: the flow value is \(5+4=9\), and the minimum of the four cut capacities is \(\min(12,9,15,9)=9\). The two calculations agree.

Common Pitfall: Counting the Wrong Arcs

A cut counts only arcs directed out of \(S\), not every arc with one endpoint on each side. For the cut \(S=\{s,a\}\) in the last example, the edge \(ab\) leaves \(S\), so its capacity 3 is counted. The arc \(sa\) stays inside \(S\), so its capacity 8 is not counted. The outgoing cut arcs are \(sb,ab,at\), giving \(4+3+2=9\). A wrong calculation that adds \(sa\) as well gives \(8+4+3+2=17\); that is not the capacity of this cut. Also, a flow value is not the sum of all arc flows: internal flow can be counted repeatedly by that sum. Compute the value at the source, then check conservation at intermediate vertices.

In a practical plan, a minimum cut identifies a set of connections whose combined capacity limits end-to-end throughput. Increasing capacity elsewhere cannot raise the maximum beyond that cut's capacity. To justify a proposed maximum, however, give both pieces of evidence: a feasible flow attaining the amount and a cut with the same capacity.

Check Your Understanding

Use the definitions and cut bound to analyze each network.

  1. Let \(V=\{s,a,t\}\) with arcs \(sa\) of capacity 5 and \(at\) of capacity 3. Give a maximum flow and a cut certifying its value.
  2. In the network of the first worked example, why does the unused capacity on \(sa\) not increase the maximum deliverable amount?
  3. Explain why the second augmenting path in the rerouting example is allowed to use \(c\to a\), even though \(c\to a\) is not an original arc.
  4. For the last example, calculate the flow value from the arcs leaving \(s\), then verify conservation at \(a\) and \(b\).
  5. State what must be checked to certify that a proposed feasible flow is maximum, and explain why those checks suffice.