70 cout <<
" " << name <<
": { ";
74 if (!first)
cout <<
", ";
75 cout << node->get_info();
87 cout <<
" Cut edges:\n";
91 <<
" --(" << arc->get_info() <<
")-- "
105 cout <<
"╔════════════════════════════════════════════════════════════════╗\n";
106 cout <<
"║ EXAMPLE 1: Network Reliability Analysis ║\n";
107 cout <<
"╚════════════════════════════════════════════════════════════════╝\n\n";
109 cout <<
"SCENARIO: A company has 6 offices connected by network links.\n";
110 cout <<
" We need to find the minimum number of links that,\n";
111 cout <<
" if cut, would split the network into two parts.\n\n";
117 cout <<
"STEP 1: Building network topology\n";
118 cout <<
" Offices: HQ, Branch1, Branch2, Branch3, Remote1, Remote2\n\n";
140 cout <<
" Network structure:\n";
141 cout <<
" Remote1\n";
143 cout <<
" Branch1--+--HQ--Branch3--Remote2\n";
145 cout <<
" Branch2-------+\n\n";
147 cout <<
" Total: " <<
network.get_num_nodes() <<
" offices, "
148 <<
network.get_num_arcs() / 2 <<
" unique links\n\n";
151 cout <<
"STEP 2: Finding minimum cut with Karger-Stein\n";
152 cout <<
" (Running 20 iterations for accuracy)\n\n";
161 cout <<
" Minimum cut size: " <<
min_cut / 2 <<
" links\n";
165 cout <<
"\nINTERPRETATION:\n";
166 cout <<
" The network can be split by cutting just " <<
min_cut / 2 <<
" link(s).\n";
167 cout <<
" RECOMMENDATION: Add redundant links to vulnerable offices.\n\n";
179 cout <<
"╔════════════════════════════════════════════════════════════════╗\n";
180 cout <<
"║ EXAMPLE 2: Weighted Network - Bandwidth Analysis ║\n";
181 cout <<
"╚════════════════════════════════════════════════════════════════╝\n\n";
183 cout <<
"SCENARIO: A data center has servers connected with varying bandwidth.\n";
184 cout <<
" Find the minimum total bandwidth that could bottleneck.\n\n";
196 cout <<
"STEP 1: Network topology with bandwidth (Gbps)\n\n";
205 cout <<
" Web1 --10-- App --20-- Cache --5-- Database\n";
206 cout <<
" Web2 --10-- | |\n";
207 cout <<
" +-------2---------+\n\n";
210 cout <<
"STEP 2: Finding minimum cut with Stoer-Wagner\n\n";
222 cout <<
"\n Bottleneck links:\n";
226 <<
" <-> " <<
datacenter.get_tgt_node(arc)->get_info()
227 <<
" (" << arc->get_info() <<
" Gbps)\n";
230 cout <<
"\nINTERPRETATION:\n";
231 cout <<
" The database access is the bottleneck at " <<
min_bandwidth / 2 <<
" Gbps.\n";
232 cout <<
" RECOMMENDATION: Upgrade Cache-Database link or add more paths.\n\n";
244 cout <<
"╔════════════════════════════════════════════════════════════════╗\n";
245 cout <<
"║ EXAMPLE 3: Community Detection in Social Network ║\n";
246 cout <<
"╚════════════════════════════════════════════════════════════════╝\n\n";
248 cout <<
"SCENARIO: A social network with two friend groups loosely connected.\n";
249 cout <<
" Find the natural division between communities.\n\n";
264 cout <<
"STEP 1: Building social connections\n\n";
279 cout <<
" Group 1 (Tech): Group 2 (Sports):\n";
280 cout <<
" Alice--Bob Dave--Eve\n";
281 cout <<
" \\ / \\ /\n";
282 cout <<
" Carol ---- Dave Frank\n";
283 cout <<
" (weak link)\n\n";
286 cout <<
"STEP 2: Running both algorithms\n\n";
300 cout <<
"KARGER-STEIN RESULT:\n";
305 cout <<
"\nSTOER-WAGNER RESULT:\n";
310 cout <<
"\nINTERPRETATION:\n";
311 cout <<
" Both algorithms identify the two communities correctly.\n";
312 cout <<
" The Carol-Dave connection is the bridge between groups.\n\n";
321 cout <<
"╔════════════════════════════════════════════════════════════════╗\n";
322 cout <<
"║ EXAMPLE 4: Algorithm Comparison ║\n";
323 cout <<
"╚════════════════════════════════════════════════════════════════╝\n\n";
325 cout <<
"SCENARIO: Compare Karger-Stein vs Stoer-Wagner on the same graph.\n\n";
372 cout <<
"KARGER-STEIN (varying iterations):\n";
375 for (
int iters : {1, 5, 10, 20, 50})
379 size_t result =
ks(g, S,
T, cut,
iters);
381 << result / 2 <<
"\n";
385 cout <<
"\nSTOER-WAGNER (deterministic):\n";
389 int result =
sw(g, S,
T, cut);
390 cout <<
" Result: min-cut = " << result / 2 <<
"\n";
392 cout <<
"\nCONCLUSION:\n";
393 cout <<
" - Karger-Stein converges to correct answer with more iterations\n";
394 cout <<
" - Stoer-Wagner always gives exact answer in one run\n";
395 cout <<
" - Choose based on: graph size, accuracy needs, weighted/unweighted\n\n";
404 cout <<
"╔════════════════════════════════════════════════════════════════╗\n";
405 cout <<
"║ EXAMPLE 5: API Usage Patterns ║\n";
406 cout <<
"╚════════════════════════════════════════════════════════════════╝\n\n";
421 cout <<
"PATTERN 1: Basic single-run (Karger-Stein)\n";
422 cout <<
"-------------------------------------------\n";
424 Karger_Stein_Min_Cut<GT> ks;
425 DynList<GT::Node*> S, T;
426 DynList<GT::Arc*> cut;
427 size_t result = ks(g, S, T, cut);
434 size_t result =
ks(g, S,
T, cut);
435 cout <<
" Result: " << result <<
"\n\n";
438 cout <<
"PATTERN 2: Multiple iterations for accuracy (Karger-Stein)\n";
439 cout <<
"-----------------------------------------------------------\n";
441 size_t result = ks(g, S, T, cut, 20);
448 size_t result =
ks(g, S,
T, cut, 20);
449 cout <<
" Result: " << result <<
"\n\n";
452 cout <<
"PATTERN 3: Reproducible results with seed\n";
453 cout <<
"------------------------------------------\n";
455 Karger_Stein_Min_Cut<GT> ks(12345); // Seed = 12345
456 // Or: ks.set_seed(12345);
466 cout <<
" Same seed → same result: " << (
r1 == r2 ?
"YES" :
"NO") <<
"\n\n";
469 cout <<
"PATTERN 4: Weighted graph (Stoer-Wagner)\n";
470 cout <<
"-----------------------------------------\n";
472 Stoer_Wagner_Min_Cut<GT> sw;
473 int weight = sw(g, S, T, cut); // Returns total weight of cut edges
480 int weight =
sw(g, S,
T, cut);
481 cout <<
" Result: " << weight <<
"\n\n";
484 cout <<
"PATTERN 5: Just the weight, no partition (Stoer-Wagner)\n";
485 cout <<
"--------------------------------------------------------\n";
487 int weight = sw.min_cut_weight(g); // Slightly faster
492 int weight =
sw.min_cut_weight(g);
493 cout <<
" Result: " << weight <<
"\n\n";
496 cout <<
"PATTERN 6: Unweighted graph with Stoer-Wagner\n";
497 cout <<
"----------------------------------------------\n";
499 Stoer_Wagner_Min_Cut<GT, Unit_Weight<GT>> sw;
500 size_t num_edges = sw(g, S, T, cut); // Counts edges, ignores weights
518 cout <<
"╔════════════════════════════════════════════════════════════════╗\n";
519 cout <<
"║ EXAMPLE 6: Algorithm Selection Guide ║\n";
520 cout <<
"╚════════════════════════════════════════════════════════════════╝\n\n";
522 cout <<
"DECISION FLOWCHART:\n";
523 cout <<
"═══════════════════\n\n";
525 cout <<
" ┌─────────────────────────────────────────┐\n";
526 cout <<
" │ Do you need the EXACT minimum cut? │\n";
527 cout <<
" └────────────────┬────────────────────────┘\n";
529 cout <<
" ┌─────────┴─────────┐\n";
534 cout <<
" ┌──────────────┐ ┌──────────────────────┐\n";
535 cout <<
" │ STOER-WAGNER │ │ Is the graph large? │\n";
536 cout <<
" │ Deterministic│ │ (n > 100) │\n";
537 cout <<
" └──────────────┘ └──────────┬───────────┘\n";
539 cout <<
" ┌─────────┴─────────┐\n";
544 cout <<
" ┌──────────────┐ ┌──────────────┐\n";
545 cout <<
" │ KARGER-STEIN │ │ STOER-WAGNER │\n";
546 cout <<
" │ O(n² log³ n) │ │ Simple cases │\n";
547 cout <<
" └──────────────┘ └──────────────┘\n\n";
549 cout <<
"COMPARISON TABLE:\n";
550 cout <<
"═════════════════\n\n";
552 cout <<
" ┌────────────────┬───────────────────┬───────────────────┐\n";
553 cout <<
" │ Criterion │ Karger-Stein │ Stoer-Wagner │\n";
554 cout <<
" ├────────────────┼───────────────────┼───────────────────┤\n";
555 cout <<
" │ Time │ O(n² log³ n) │ O(nm + n² log n) │\n";
556 cout <<
" │ Space │ O(n + m) │ O(n²) │\n";
557 cout <<
" │ Deterministic? │ No (randomized) │ Yes │\n";
558 cout <<
" │ Weighted? │ No │ Yes │\n";
559 cout <<
" │ Exact? │ High probability │ Always │\n";
560 cout <<
" │ Large graphs │ ✓ Better │ OK │\n";
561 cout <<
" │ Small graphs │ OK │ ✓ Better │\n";
562 cout <<
" └────────────────┴───────────────────┴───────────────────┘\n\n";
564 cout <<
"PRACTICAL RECOMMENDATIONS:\n";
565 cout <<
"══════════════════════════\n\n";
567 cout <<
" 1. NETWORK RELIABILITY → Stoer-Wagner (exact answer matters)\n";
568 cout <<
" 2. BANDWIDTH ANALYSIS → Stoer-Wagner (needs weights)\n";
569 cout <<
" 3. COMMUNITY DETECTION → Either (approximate OK)\n";
570 cout <<
" 4. LARGE SOCIAL GRAPH → Karger-Stein (faster)\n";
571 cout <<
" 5. VLSI DESIGN → Stoer-Wagner (precision critical)\n\n";
581 cout <<
"████████████████████████████████████████████████████████████████████\n";
583 cout <<
"██ MINIMUM CUT ALGORITHMS - EDUCATIONAL EXAMPLES ██\n";
584 cout <<
"██ Karger-Stein (Randomized) & Stoer-Wagner (Deterministic) ██\n";
586 cout <<
"████████████████████████████████████████████████████████████████████\n";
596 cout <<
"════════════════════════════════════════════════════════════════════\n";
597 cout <<
" All examples completed successfully!\n";
598 cout <<
"════════════════════════════════════════════════════════════════════\n\n";
Karger-Stein randomized min-cut algorithm (alias for Karger.H fast method).
Stoer-Wagner deterministic min-cut algorithm.
Dynamic singly linked list with functional programming support.
Karger's randomized minimum cut algorithm.
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Stoer-Wagner deterministic minimum cut algorithm.
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)
void example_weighted_bandwidth()
void example_community_detection()
void print_cut_edges(GT &g, const DynList< typename GT::Arc * > &cut)
void example_algorithm_comparison()
void print_partition(const string &name, const DynList< typename GT::Node * > &partition)
void example_network_reliability()
void example_algorithm_selection()
void example_api_patterns()
Main namespace for Aleph-w library functions.
std::pair< TgtContainer< typename SrcContainer::Item_Type >, TgtContainer< typename SrcContainer::Item_Type > > partition(const SrcContainer &c, std::function< bool(const typename SrcContainer::Item_Type &)> operation)
Partition a container into two based on a predicate.
std::decay_t< typename HeadC::Item_Type > T
Net::Flow_Type min_cut(Net &net, DynSetTree< typename Net::Node * > &vs, DynSetTree< typename Net::Node * > &vt, DynList< typename Net::Arc * > &cuts, DynList< typename Net::Arc * > &cutt)
Compute max flow and the corresponding minimum cut.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Arc of graph implemented with double-linked adjacency lists.
Generic graph and digraph implementations.