137#include <tclap/CmdLine.h>
140using namespace Aleph;
251 cout <<
"\nEdge flows (flow/capacity):" <<
endl;
256 for (
auto it = net.
get_arc_it(); it.has_curr(); it.next())
258 auto* arc = it.get_curr();
262 cout <<
" " <<
setw(10) << left << src->get_info()
263 <<
" ---> " <<
setw(10) << left << tgt->get_info()
264 << right <<
" : " <<
setw(3) << arc->flow
265 <<
" / " <<
setw(3) << arc->cap;
270 double util = 100.0 * arc->flow / arc->cap;
272 if (arc->flow == arc->cap)
273 cout <<
" [SATURATED]";
292 cout <<
"\n=== Min-Cut (Dual of Max-Flow) ===" <<
endl;
293 cout <<
"\nBy the Max-Flow Min-Cut Theorem:" <<
endl;
294 cout <<
" Maximum flow value = Minimum cut capacity" <<
endl;
296 cout <<
"\nSaturated edges (part of min-cut):" <<
endl;
298 for (
auto it = net.
get_arc_it(); it.has_curr(); it.next())
300 auto* arc = it.get_curr();
301 if (arc->flow == arc->cap && arc->cap > 0)
305 cout <<
" " << src->get_info() <<
" -> "
306 << tgt->get_info() <<
" (capacity " << arc->cap <<
")" <<
endl;
310 cout <<
"\nNote: The min-cut separates source from sink." <<
endl;
311 cout <<
"Cutting these edges disconnects source from sink." <<
endl;
319 cout <<
"\n=== Bipartite Matching via Max-Flow ===" <<
endl;
321 cout <<
"\nProblem: Assign workers to jobs (each worker can do some jobs)" <<
endl;
359 cout <<
" Alice: Coding, Design" <<
endl;
360 cout <<
" Bob: Coding, Testing" <<
endl;
361 cout <<
" Carol: Design, Testing" <<
endl;
367 cout <<
"\nOptimal assignment:" <<
endl;
369 for (
auto it = net.
get_arc_it(); it.has_curr(); it.next())
371 auto* arc = it.get_curr();
381 cout <<
" " << src->get_info() <<
" -> "
382 << tgt->get_info() <<
endl;
391 TCLAP::CmdLine
cmd(
"Network Flow Example",
' ',
"1.0");
393 TCLAP::SwitchArg
simpleArg(
"s",
"simple",
394 "Use simple water network",
false);
396 "Use complex datacenter network",
false);
397 TCLAP::SwitchArg
matchArg(
"m",
"matching",
398 "Demonstrate bipartite matching",
false);
399 TCLAP::SwitchArg
allArg(
"a",
"all",
400 "Run all demos",
false);
402 "Show detailed output",
false);
422 cout <<
"=== Maximum Flow Problem ===" <<
endl;
423 cout <<
"Algorithm used: Ford-Fulkerson (DFS augmenting paths)" <<
endl;
427 cout <<
"\n" << string(50,
'=') <<
endl;
428 cout <<
"Water Distribution Network" <<
endl;
434 cout <<
"\n--- Computing Maximum Flow ---" <<
endl;
438 cout <<
"\n*** MAXIMUM FLOW: " << max_flow <<
" units ***" <<
endl;
445 cout <<
"\n" << string(50,
'=') <<
endl;
446 cout <<
"Data Center Network" <<
endl;
452 cout <<
"\n--- Computing Maximum Flow ---" <<
endl;
456 cout <<
"\n*** MAXIMUM FLOW: " << max_flow <<
" units ***" <<
endl;
461 cout <<
"\n" << string(50,
'=') <<
endl;
465 cout <<
"\n=== Algorithm Summary ===" <<
endl;
466 cout <<
"Ford-Fulkerson: O(E * max_flow)" <<
endl;
467 cout <<
"Edmonds-Karp: O(V * E²) - uses BFS" <<
endl;
468 cout <<
"Dinic: O(V² * E) - uses level graphs" <<
endl;
472 catch (TCLAP::ArgException& e)
474 cerr <<
"Error: " << e.error() <<
" for arg " << e.argId() <<
endl;
auto get_arc_it() const noexcept
Obtains an iterator to the arc of graph.
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
constexpr size_t get_num_arcs() const noexcept
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
Main namespace for Aleph-w library functions.
Net::Flow_Type ford_fulkerson_maximum_flow(Net &net)
Maximize flow using the Ford-Fulkerson algorithm.
DynList< T > maps(const C &c, Op op)
Classic map operation.
FlowNet build_datacenter_network()
Build a more complex network.
void demonstrate_min_cut(FlowNet &net)
Demonstrate min-cut (dual of max-flow)
void print_network(FlowNet &net, const string &title)
Print network structure and flow.
void demonstrate_bipartite_matching()
Demonstrate bipartite matching as max-flow.
FlowNet build_water_network()
Build a sample flow network.
Empty placeholder class with no data members.
Arc of a flow network implemented with adjacency lists.
Flow network implemented with adjacency lists.
Node * insert_node(const Node_Type &node_info)
Insert a new node by copying node_info.
bool is_source(Node *node) const noexcept
Return true if node is a source.
Node * get_source() const
Return an arbitrary source node.
Arc * insert_arc(Node *src_node, Node *tgt_node, const Flow_Type &cap, const Flow_Type &flow, const typename Arc::Arc_Type &arc_info=Arc_Type())
Insert a capacitated arc with an initial flow.
Node * get_sink() const
Return an arbitrary sink node.
bool is_sink(Node *node) const noexcept
Return true if node is a sink.
Network flow graph structures.