12.14 Circulation with Demands
So far, flow networks have had a source and a sink.
12.14 Circulation with Demands
Problem
So far, flow networks have had a source and a sink. Flow starts at s, moves through the graph, and ends at t.
Many real systems are not organized that way.
A supply network may contain several producers and several consumers. A transportation system may require certain minimum shipments on specific routes. A scheduling model may require every department to receive a fixed amount of coverage. A logistics graph may have lower and upper bounds on each connection.
In these problems, the question is not always:
How much can we send from s to t?
The question is often:
Can we assign flows to all edges so that every local requirement is satisfied?
This is the circulation problem.
Solution
Use a flow model with lower bounds, upper bounds, and vertex balance constraints.
Each edge has:
lower(u, v) ≤ flow(u, v) ≤ capacity(u, v)
The lower bound says that at least that much flow must use the edge.
A circulation has no special source or sink. Instead, every vertex must satisfy conservation:
incoming flow = outgoing flow
When vertices have supplies or demands, we convert those requirements into an ordinary maximum-flow instance using a super source and a super sink.
Basic Circulation
In a pure circulation problem, every vertex conserves flow.
Example:
A -> B
B -> C
C -> A
If each edge carries 5 units, every vertex receives 5 and sends 5.
This is a circulation.
Unlike maximum flow, no vertex is designated as the global origin or destination.
Lower and Upper Bounds
A bounded edge has two values:
| Symbol | Meaning |
|---|---|
l(u, v) |
Lower bound |
c(u, v) |
Upper capacity |
The valid flow range is:
l(u, v) ≤ f(u, v) ≤ c(u, v)
Example:
| Edge | Lower | Capacity |
|---|---|---|
| A -> B | 3 | 10 |
The edge must carry at least 3 units and at most 10 units.
This is common in contracts, scheduling, and logistics.
Removing Lower Bounds
Lower bounds make the problem awkward because every edge starts with an obligation.
The standard trick is to satisfy each lower bound immediately.
For every edge:
u -> v
with lower bound l and capacity c, define a residual capacity:
c' = c - l
Then record the balance effect:
balance[u] -= l
balance[v] += l
Interpretation:
uhas already sentlunits.vhas already receivedlunits.- The remaining adjustable capacity is
c - l.
After this transformation, every edge has lower bound zero.
Example
Edge:
| Edge | Lower | Capacity |
|---|---|---|
| A -> B | 3 | 10 |
Replace it with:
| Edge | Capacity |
|---|---|
| A -> B | 7 |
Update balances:
| Vertex | Balance Change |
|---|---|
| A | -3 |
| B | +3 |
Now the max-flow part only decides how much additional flow, from 0 to 7, should travel from A to B.
Balance Interpretation
After removing all lower bounds, each vertex has a balance.
Use this convention:
| Balance | Meaning |
|---|---|
| Positive | Vertex has excess demand to absorb |
| Negative | Vertex has excess supply to send |
If:
balance[v] > 0
then vertex v needs that much incoming flow.
If:
balance[v] < 0
then vertex v must send out -balance[v] units.
Feasibility Transformation
To test whether a feasible circulation exists:
- Remove lower bounds.
- Compute vertex balances.
- Add a super source
SS. - Add a super sink
TT. - For every vertex with positive balance, add:
SS -> v
capacity = balance[v]
- For every vertex with negative balance, add:
v -> TT
capacity = -balance[v]
- Run max flow from
SStoTT. - A feasible circulation exists if all edges out of
SSare saturated.
This converts circulation feasibility into ordinary max flow.
Small Example
Original edges:
| Edge | Lower | Capacity |
|---|---|---|
| A -> B | 3 | 8 |
| B -> C | 2 | 6 |
| C -> A | 1 | 5 |
Remove lower bounds:
| Edge | New Capacity |
|---|---|
| A -> B | 5 |
| B -> C | 4 |
| C -> A | 4 |
Balances:
| Vertex | Calculation | Balance |
|---|---|---|
| A | -3 + 1 | -2 |
| B | +3 - 2 | 1 |
| C | +2 - 1 | 1 |
Add:
| Edge | Capacity |
|---|---|
| A -> TT | 2 |
| SS -> B | 1 |
| SS -> C | 1 |
If max flow can send 2 units from SS to TT, then the original bounded circulation is feasible.
Recovering Original Flows
After max flow succeeds, recover each original edge flow by adding back its lower bound.
For each original edge:
originalFlow(u, v) = lower(u, v) + computedFlow(u, v)
Example:
| Edge | Lower | Computed Extra | Original Flow |
|---|---|---|---|
| A -> B | 3 | 2 | 5 |
| B -> C | 2 | 0 | 2 |
The returned flow now respects all lower and upper bounds.
Circulation with Supplies and Demands
Some models attach supply or demand directly to vertices.
Example:
| Vertex | Requirement |
|---|---|
| Factory | supply 10 |
| Store A | demand 4 |
| Store B | demand 6 |
You can represent this with balances directly.
One common convention:
| Vertex Type | Balance |
|---|---|
| Supply vertex | negative |
| Demand vertex | positive |
Then use the same super-source and super-sink transformation.
Feasibility Condition
Before running max flow, the total balance must sum to zero.
sum(balance[v]) = 0
If not, feasibility is impossible.
The network cannot consume more flow than it produces, and it cannot produce more flow than it consumes.
This is an inexpensive early check.
Converting s-t Flow with Lower Bounds
Suppose you want to send flow from s to t, but edges have lower bounds.
Add an artificial edge:
t -> s
capacity = INF
Then solve circulation with lower bounds.
This edge closes the loop and allows the circulation machinery to handle the source and sink requirements.
After feasibility is established, the flow on t -> s represents the amount sent from s to t.
Minimum Feasible Flow
Sometimes the problem asks for the smallest feasible flow from s to t.
Use the circulation transformation with edge:
t -> s
Then minimize the flow on that edge, often by running additional residual adjustments or binary search depending on the formulation.
Maximum Feasible Flow
For maximum feasible flow with lower bounds:
- Check feasibility using circulation.
- Remove the artificial super source and super sink.
- Run additional max flow from
stotin the residual graph. - Add that value to the already feasible flow.
This separates feasibility from optimization.
Common Applications
Shipment Contracts
A supplier must send at least a contracted minimum along certain routes, but cannot exceed route capacity.
Workforce Scheduling
Each shift must receive a minimum number of workers, while workers have maximum availability.
Course Allocation
Courses may require minimum enrollment and have maximum capacity.
Traffic Engineering
Certain links must carry required baseline traffic while respecting bandwidth limits.
Production Planning
Factories have supply limits, warehouses have throughput limits, and customers have fixed demand.
Implementation Pattern
Store each original edge with:
from
to
lower
capacity
edgeIndex
When building the transformed graph:
addEdge(from, to, capacity - lower)
balance[from] -= lower
balance[to] += lower
After solving, read the residual state of the transformed edge and add lower back.
Keep artificial edges separate so they do not appear in the final answer.
Complexity
The transformation adds:
2
vertices and at most:
V
extra edges.
The running time is essentially the running time of the max-flow algorithm used.
With Dinic:
O(V²E)
in the general case, with the transformed graph size.
In practice, the transformation overhead is small.
Common Mistakes
Forgetting to Subtract Lower Bounds
The transformed capacity must be:
capacity - lower
not the original capacity.
Reversing Balance Signs
Pick one sign convention and use it consistently. A common convention is: lower-bound flow subtracts from the tail and adds to the head.
Checking Only Total Flow
Feasibility requires all edges from the super source to be saturated. A nonzero flow is not enough.
Forgetting to Restore Lower Bounds
The flow computed on transformed edges is only the extra flow beyond the lower bound.
Using Too Small an Infinity
For artificial edges such as t -> s, choose an upper bound at least as large as the maximum possible total flow in the model.
Discussion
Circulation with demands is the standard way to handle flow problems that have local obligations. Lower bounds represent required movement. Vertex balances represent supply and demand. Super source and super sink edges convert those obligations into an ordinary max-flow feasibility test.
This technique is a modeling tool more than a new algorithm. Once the transformation is correct, the rest is ordinary max flow.
Takeaway
Circulation removes the special role of source and sink and asks whether all local flow requirements can be satisfied. Lower bounds are handled by pre-sending required flow, recording vertex balances, and using a super source and super sink to repair the imbalance.
A feasible circulation exists exactly when the max-flow computation saturates every edge leaving the super source.