42 cout <<
"=== Multi-Commodity Flow: Educational Examples ===\n\n";
48 cout <<
"--- Example 1: Two Data Streams Sharing Network ---\n\n";
50 cout <<
"SCENARIO: Data center with two applications\n";
51 cout <<
"=========================================\n\n";
53 cout <<
"COMMODITY 1: Video streaming\n";
54 cout <<
" Source: Server_A\n";
55 cout <<
" Sink: CDN_1\n";
56 cout <<
" Demand: 100 Mbps\n\n";
58 cout <<
"COMMODITY 2: Database backup\n";
59 cout <<
" Source: Server_B\n";
60 cout <<
" Sink: CDN_2\n";
61 cout <<
" Demand: 80 Mbps\n\n";
63 cout <<
"SHARED NETWORK:\n";
64 cout <<
" Server_A ----\n";
66 cout <<
" Router (100 Mbps capacity)\n";
68 cout <<
" Server_B ----\n";
70 cout <<
" Switch (100 Mbps capacity)\n";
72 cout <<
" CDN_1 CDN_2\n\n";
74 cout <<
"CONSTRAINT: Router has only 100 Mbps total capacity\n";
75 cout <<
" Commodity 1 wants: 100 Mbps\n";
76 cout <<
" Commodity 2 wants: 80 Mbps\n";
77 cout <<
" Total demand: 180 Mbps\n";
78 cout <<
" Available: 100 Mbps\n";
79 cout <<
" CONFLICT! Cannot satisfy both fully\n\n";
81 cout <<
"POSSIBLE SOLUTIONS:\n";
82 cout <<
" 1. Priority: Give commodity 1 full 100 Mbps, commodity 2 gets 0\n";
83 cout <<
" 2. Fair share: Split 50/50 → 50 Mbps each\n";
84 cout <<
" 3. Weighted: 60% to commodity 1, 40% to commodity 2\n";
85 cout <<
" 4. Time-sharing: Alternate between commodities\n\n";
87 cout <<
"KEY INSIGHT: Must balance competing demands\n";
88 cout <<
" Unlike single-commodity where solution is clear\n\n";
95 cout <<
"--- Example 2: Feasibility Check ---\n\n";
97 cout <<
"FEASIBLE CASE:\n";
98 cout <<
"==============\n\n";
100 cout <<
"Network:\n";
101 cout <<
" S1 --100--> Hub --150--> T1\n";
103 cout <<
" S2 --80----->+--120--> T2\n\n";
105 cout <<
"Commodity 1: S1 → T1, demand 60\n";
106 cout <<
"Commodity 2: S2 → T2, demand 70\n\n";
108 cout <<
"Check capacities:\n";
109 cout <<
" S1 → Hub: Need 60, have 100 ✓\n";
110 cout <<
" S2 → Hub: Need 70, have 80 ✓\n";
111 cout <<
" Hub → T1: Need 60, have 150 ✓\n";
112 cout <<
" Hub → T2: Need 70, have 120 ✓\n\n";
114 cout <<
"RESULT: FEASIBLE ✓\n";
115 cout <<
" Both commodities can be routed\n\n";
117 cout <<
"INFEASIBLE CASE:\n";
118 cout <<
"================\n\n";
120 cout <<
"Same network, different demands:\n";
121 cout <<
"Commodity 1: S1 → T1, demand 90\n";
122 cout <<
"Commodity 2: S2 → T2, demand 80\n\n";
124 cout <<
"Check capacities:\n";
125 cout <<
" S1 → Hub: Need 90, have 100 ✓\n";
126 cout <<
" S2 → Hub: Need 80, have 80 ✓\n";
127 cout <<
" Hub outgoing: Need 90+80=170, have 150+120=270 ✓\n";
128 cout <<
" BUT: Hub is single node with limited throughput!\n\n";
130 cout <<
"RESULT: May be INFEASIBLE\n";
131 cout <<
" Depends on node capacity constraints\n\n";
138 cout <<
"--- Example 3: Multiple Paths ---\n\n";
140 cout <<
"ADVANTAGE: Multiple commodities can use DIFFERENT paths\n";
141 cout <<
"======================================================\n\n";
143 cout <<
"Network:\n";
144 cout <<
" Path 1 (direct)\n";
145 cout <<
" S1 ========100========> T1\n";
148 cout <<
" 50 \\ Hub (relay) / 50\n";
150 cout <<
" \\ |50 /\n";
152 cout <<
" S2 ====\\===+=====/ T2\n";
153 cout <<
" 80 \\ / 80\n";
154 cout <<
" Path 2\n\n";
156 cout <<
"Commodity 1: S1 → T1, demand 60\n";
157 cout <<
"Commodity 2: S2 → T2, demand 70\n\n";
159 cout <<
"SMART ROUTING:\n";
160 cout <<
" Commodity 1: Use direct path (S1 → T1)\n";
161 cout <<
" Flow: 60 through 100-capacity link ✓\n\n";
163 cout <<
" Commodity 2: Use relay path (S2 → Hub → T2)\n";
164 cout <<
" Flow: 70 split between two 50-capacity links\n";
165 cout <<
" Send 50 through S2→Hub, then Hub→T2\n";
166 cout <<
" Send 20 through direct S2→T2\n\n";
168 cout <<
"KEY STRATEGY: Route different commodities on different paths\n";
169 cout <<
" Maximize utilization of all network resources\n\n";
176 cout <<
"--- Example 4: Minimizing Cost ---\n\n";
178 cout <<
"PROBLEM: Not just feasibility, but OPTIMAL routing\n";
179 cout <<
"=================================================\n\n";
181 cout <<
"Each arc has:\n";
182 cout <<
" * Capacity: Maximum flow\n";
183 cout <<
" * Cost per unit: Price to send 1 unit\n\n";
185 cout <<
"EXAMPLE:\n";
186 cout <<
" Path A: Capacity 100, Cost $2/unit\n";
187 cout <<
" Path B: Capacity 50, Cost $1/unit (cheaper but limited)\n\n";
189 cout <<
"STRATEGY:\n";
190 cout <<
" 1. Fill cheap path B first (50 units at $1 = $50)\n";
191 cout <<
" 2. Use expensive path A for overflow (50 units at $2 = $100)\n";
192 cout <<
" 3. Total: 100 units for $150\n\n";
194 cout <<
"NAIVE APPROACH:\n";
195 cout <<
" Use only path A: 100 units at $2 = $200\n";
196 cout <<
" Wastes $50!\n\n";
198 cout <<
"OPTIMIZATION GOAL:\n";
199 cout <<
" Minimize: Sum of (flow * cost) across all arcs\n";
200 cout <<
" Subject to:\n";
201 cout <<
" - Flow conservation\n";
202 cout <<
" - Capacity constraints\n";
203 cout <<
" - Commodity demands satisfied\n\n";
205 cout <<
"ALGORITHM: Linear programming or min-cost flow\n\n";
212 cout <<
"--- Example 5: Telephone Network ---\n\n";
214 cout <<
"REAL-WORLD: Telephone calls sharing network\n";
215 cout <<
"=========================================\n\n";
217 cout <<
"COMMODITIES: Individual phone calls\n";
218 cout <<
" * Call 1: NYC → LA\n";
219 cout <<
" * Call 2: Boston → SF\n";
220 cout <<
" * Call 3: NYC → Chicago\n";
221 cout <<
" * ... (thousands of simultaneous calls)\n\n";
223 cout <<
"SHARED RESOURCES:\n";
224 cout <<
" * Fiber optic cables (limited bandwidth)\n";
225 cout <<
" * Routing switches (limited capacity)\n";
226 cout <<
" * Cross-country trunk lines\n\n";
228 cout <<
"CHALLENGES:\n";
229 cout <<
" 1. DYNAMIC: Calls start/end continuously\n";
230 cout <<
" Must reroute in real-time\n\n";
232 cout <<
" 2. QUALITY: Each call needs minimum bandwidth\n";
233 cout <<
" Cannot just 'share' bandwidth arbitrarily\n\n";
235 cout <<
" 3. RELIABILITY: Calls shouldn't drop\n";
236 cout <<
" Need backup routes if link fails\n\n";
238 cout <<
" 4. COST: Long-distance links are expensive\n";
239 cout <<
" Minimize total routing cost\n\n";
241 cout <<
"SOLUTION APPROACH:\n";
242 cout <<
" * Online algorithms: Handle calls as they arrive\n";
243 cout <<
" * Load balancing: Distribute across network\n";
244 cout <<
" * Admission control: Reject if no capacity\n";
245 cout <<
" * Dynamic rerouting: Adapt to failures\n\n";
252 cout <<
"--- Example 6: Multi-Product Distribution ---\n\n";
254 cout <<
"SCENARIO: Logistics company\n";
255 cout <<
"==========================\n\n";
257 cout <<
"PRODUCTS (commodities):\n";
258 cout <<
" * Electronics: Factory_A → Store_X (50 tons)\n";
259 cout <<
" * Furniture: Factory_B → Store_Y (80 tons)\n";
260 cout <<
" * Food: Factory_C → Store_Z (30 tons)\n\n";
262 cout <<
"SHARED WAREHOUSES:\n";
263 cout <<
" * Hub_1: Capacity 100 tons (receives from all factories)\n";
264 cout <<
" * Hub_2: Capacity 80 tons (distributes to all stores)\n\n";
266 cout <<
"TRUCK FLEET: Limited capacity\n";
267 cout <<
" * Route A: 70 tons/day\n";
268 cout <<
" * Route B: 50 tons/day\n";
269 cout <<
" * Route C: 60 tons/day\n\n";
271 cout <<
"OPTIMIZATION:\n";
272 cout <<
" 1. Which products use which routes?\n";
273 cout <<
" 2. How to mix products on trucks?\n";
274 cout <<
" 3. Minimize delivery time or cost?\n\n";
276 cout <<
"CONSTRAINT: Different products CAN share trucks\n";
277 cout <<
" But total weight cannot exceed capacity\n\n";
280 cout <<
"=== SUMMARY: Multi-Commodity Flow ===\n";
281 cout <<
"\n1. DEFINITION:\n";
282 cout <<
" Multiple flow types (commodities) sharing same network\n";
283 cout <<
" Each commodity has own source/sink/demand\n";
284 cout <<
" Arc capacities are SHARED across commodities\n";
285 cout <<
"\n2. KEY DIFFERENCE vs SINGLE-COMMODITY:\n";
286 cout <<
" Single: One source-sink pair, clear optimal solution\n";
287 cout <<
" Multi: Many source-sink pairs, must balance conflicts\n";
288 cout <<
"\n3. COMPLEXITY:\n";
289 cout <<
" Single-commodity: Polynomial time (max-flow)\n";
290 cout <<
" Multi-commodity: NP-hard in general\n";
291 cout <<
" Requires LP or approximation\n";
292 cout <<
"\n4. PROBLEM VARIANTS:\n";
293 cout <<
" * Feasibility: Can all demands be met?\n";
294 cout <<
" * Min-cost: Minimize total routing cost\n";
295 cout <<
" * Max-throughput: Maximize total flow\n";
296 cout <<
" * Fair allocation: Balance between commodities\n";
297 cout <<
"\n5. REAL-WORLD APPLICATIONS:\n";
298 cout <<
" ✓ Telecommunications (calls, data streams)\n";
299 cout <<
" ✓ Transportation (goods, passengers)\n";
300 cout <<
" ✓ Supply chains (multiple products)\n";
301 cout <<
" ✓ Computer networks (packet routing)\n";
302 cout <<
" ✓ Power grids (multiple generators/consumers)\n";
303 cout <<
"\n6. SOLUTION APPROACHES:\n";
304 cout <<
" * Linear Programming (exact, polynomial for fixed k)\n";
305 cout <<
" * Approximation algorithms (fast, near-optimal)\n";
306 cout <<
" * Heuristics (practical, no guarantees)\n";
307 cout <<
" * Column generation (for large instances)\n";
308 cout <<
"\n7. KEY TRADE-OFFS:\n";
309 cout <<
" Complexity vs Optimality\n";
310 cout <<
" Speed vs Solution Quality\n";
311 cout <<
" Fairness vs Efficiency\n";
312 cout <<
" Static vs Dynamic routing\n";
Main namespace for Aleph-w library functions.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Generic graph and digraph implementations.