Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
net_apps_example.cc
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
247#include <iostream>
248#include <iomanip>
249#include <vector>
250#include <string>
251#include <map>
252#include <cstring>
253#include <net_apps.H>
254
255using namespace std;
256using namespace Aleph;
257
258static bool has_flag(int argc, char* argv[], const char* flag)
259{
260 for (int i = 1; i < argc; ++i)
261 if (std::strcmp(argv[i], flag) == 0)
262 return true;
263 return false;
264}
265
276{
277 cout << "\n" << string(60, '=') << endl;
278 cout << "Demo 1: Project Selection (Max Closure Problem)" << endl;
279 cout << string(60, '=') << endl;
280
281 cout << "\nScenario: A tech company is planning next year's projects." << endl;
282 cout << "\nAvailable projects:" << endl;
283 cout << " ID Name Profit Prerequisites" << endl;
284 cout << " -- ---- ------ -------------" << endl;
285 cout << " 0 Mobile App +$100K -" << endl;
286 cout << " 1 Backend API +$80K -" << endl;
287 cout << " 2 Cloud Migration -$50K (infrastructure)" << endl;
288 cout << " 3 ML Feature +$120K 2 (needs cloud)" << endl;
289 cout << " 4 Security Audit -$30K (compliance)" << endl;
290 cout << " 5 GDPR Compliance +$60K 4 (needs audit)" << endl;
291
293 {0, 100000, {}, "Mobile App"},
294 {1, 80000, {}, "Backend API"},
295 {2, -50000, {}, "Cloud Migration"},
296 {3, 120000, {2}, "ML Feature"}, // Requires Cloud Migration
297 {4, -30000, {}, "Security Audit"},
298 {5, 60000, {4}, "GDPR Compliance"} // Requires Security Audit
299 };
300
301 cout << "\n--- Solving with Max-Flow Min-Cut ---" << endl;
302
303 auto result = solve_project_selection(projects);
304
305 cout << "\n*** Optimal Selection ***" << endl;
306 cout << "Maximum profit: $" << fixed << setprecision(0)
307 << result.max_profit << endl;
308
309 cout << "\nSelected projects:" << endl;
310 for (size_t id : result.selected)
311 {
312 const auto& p = projects[id];
313 cout << " [" << id << "] " << p.name
314 << " (" << (p.profit >= 0 ? "+" : "") << "$" << p.profit << ")" << endl;
315 }
316
317 cout << "\nAnalysis:" << endl;
318 cout << " Total revenue: $" << result.total_revenue << endl;
319 cout << " Total costs: $" << result.total_cost << endl;
320 cout << " Net profit: $" << result.max_profit << endl;
321
322 cout << "\nNote: The ML Feature (+$120K) is selected despite requiring" << endl;
323 cout << "Cloud Migration (-$50K) because net profit is +$70K." << endl;
324}
325
334{
335 cout << "\n" << string(60, '=') << endl;
336 cout << "Demo 2: Image Segmentation (Graph Cuts)" << endl;
337 cout << string(60, '=') << endl;
338
339 cout << "\nScenario: Segment a 4x4 grayscale image." << endl;
340 cout << "Dark pixels (low intensity) -> Background (label 0)" << endl;
341 cout << "Bright pixels (high intensity) -> Foreground (label 1)" << endl;
342
343 // Simulated 4x4 image (grayscale intensities 0-255)
344 // Dark regions are background, bright regions are foreground
346 {30, 40, 180, 200},
347 {35, 45, 190, 210},
348 {40, 50, 185, 195},
349 {50, 60, 170, 180}
350 };
351
352 cout << "\nOriginal image (intensities):" << endl;
353 for (const auto& row : image)
354 {
355 cout << " ";
356 for (int val : row)
357 cout << setw(4) << val;
358 cout << endl;
359 }
360
361 // Convert to data costs
362 // Cost of labeling pixel as background = intensity (high = expensive)
363 // Cost of labeling pixel as foreground = 255 - intensity
365 vector<array<double, 2>>(4));
366
367 for (int i = 0; i < 4; ++i)
368 for (int j = 0; j < 4; ++j)
369 {
370 double intensity = image[i][j];
371 data_cost[i][j][0] = intensity; // Cost of background
372 data_cost[i][j][1] = 255 - intensity; // Cost of foreground
373 }
374
375 double smoothness = 50.0; // Penalty for adjacent pixels with different labels
376
377 cout << "\nSmooth penalty for label changes: " << smoothness << endl;
378
379 cout << "\n--- Computing Optimal Segmentation ---" << endl;
380
381 auto result = segment_image(4, 4, data_cost, smoothness);
382
383 cout << "\nSegmentation result (0=background, 1=foreground):" << endl;
384 for (const auto& row : result.labels)
385 {
386 cout << " ";
387 for (int label : row)
388 cout << setw(4) << (label ? "FG" : "BG");
389 cout << endl;
390 }
391
392 cout << "\nTotal energy: " << result.energy << endl;
393 cout << "(Lower energy = better segmentation)" << endl;
394
395 cout << "\nVisualization (# = foreground, . = background):" << endl;
396 for (const auto& row : result.labels)
397 {
398 cout << " ";
399 for (int label : row)
400 cout << (label ? " # " : " . ");
401 cout << endl;
402 }
403
404 cout << "\nNote: The algorithm correctly separates the bright right half" << endl;
405 cout << "(foreground) from the dark left half (background)." << endl;
406}
407
415{
416 cout << "\n" << string(60, '=') << endl;
417 cout << "Demo 3: Baseball Elimination" << endl;
418 cout << string(60, '=') << endl;
419
420 cout << "\nScenario: Late-season standings in a 4-team division." << endl;
421 cout << "\nCurrent standings:" << endl;
422 cout << " Team Wins Losses Remaining" << endl;
423 cout << " ---- ---- ------ ---------" << endl;
424 cout << " Yankees 83 71 8" << endl;
425 cout << " Red Sox 80 79 3" << endl;
426 cout << " Blue Jays 78 78 6" << endl;
427 cout << " Orioles 75 84 3" << endl;
428
430
431 // Create teams and set their against games
432 Team yankees("Yankees", 83, 71, 8);
433 yankees.against = {0, 1, 2, 1}; // Games vs each team
434 teams.push_back(yankees);
435
436 Team redsox("Red Sox", 80, 79, 3);
437 redsox.against = {1, 0, 0, 2};
438 teams.push_back(redsox);
439
440 Team bluejays("Blue Jays", 78, 78, 6);
441 bluejays.against = {2, 0, 0, 4};
442 teams.push_back(bluejays);
443
444 Team orioles("Orioles", 75, 84, 3);
445 orioles.against = {1, 2, 4, 0};
446 teams.push_back(orioles);
447
448 cout << "\nRemaining games matrix:" << endl;
449 cout << " NYY BOS TOR BAL" << endl;
450 for (size_t i = 0; i < teams.size(); ++i)
451 {
452 cout << " " << setw(4) << left << teams[i].name.substr(0, 3) << ": ";
453 for (int g : teams[i].against)
454 cout << setw(4) << g;
455 cout << endl;
456 }
457
458 cout << "\n--- Checking Each Team's Elimination Status ---" << endl;
459
460 for (size_t i = 0; i < teams.size(); ++i)
461 {
462 auto result = check_baseball_elimination(teams, i);
463
464 cout << "\n" << teams[i].name << ": ";
465 if (result.eliminated)
466 {
467 cout << "ELIMINATED!" << endl;
468 cout << " Max possible wins: " << result.max_possible_wins << endl;
469 if (!result.certificate.empty())
470 {
471 cout << " Certificate (teams blocking): ";
472 for (size_t t : result.certificate)
473 cout << teams[t].name << " ";
474 cout << endl;
475 }
476 }
477 else
478 {
479 cout << "Can still win!" << endl;
480 cout << " Max possible wins: " << result.max_possible_wins << endl;
481 }
482 }
483
484 cout << "\nNote: A team is eliminated if the sum of wins among a subset" << endl;
485 cout << "of other teams, plus their remaining games among themselves," << endl;
486 cout << "makes it impossible to finish in first place." << endl;
487}
488
498{
499 cout << "\n" << string(60, '=') << endl;
500 cout << "Demo 4: Survey Design" << endl;
501 cout << string(60, '=') << endl;
502
503 cout << "\nScenario: Design a customer feedback survey." << endl;
504 cout << "\nQuestions:" << endl;
505 cout << " Q0: Product quality (needs 2-4 responses)" << endl;
506 cout << " Q1: Customer service (needs 2-3 responses)" << endl;
507 cout << " Q2: Pricing feedback (needs 1-3 responses)" << endl;
508
509 cout << "\nRespondents:" << endl;
510 cout << " R0: Can answer Q0, Q1 (answers 1-2 questions)" << endl;
511 cout << " R1: Can answer Q0, Q2 (answers 1-2 questions)" << endl;
512 cout << " R2: Can answer Q1, Q2 (answers 1-2 questions)" << endl;
513 cout << " R3: Can answer Q0, Q1, Q2 (answers 2-3 questions)" << endl;
514
516 {0, 2, 4}, // Q0: min 2, max 4 responses
517 {1, 2, 3}, // Q1: min 2, max 3 responses
518 {2, 1, 3} // Q2: min 1, max 3 responses
519 };
520
522 {0, 1, 2, {0, 1}}, // R0: 1-2 questions, eligible for Q0, Q1
523 {1, 1, 2, {0, 2}}, // R1: 1-2 questions, eligible for Q0, Q2
524 {2, 1, 2, {1, 2}}, // R2: 1-2 questions, eligible for Q1, Q2
525 {3, 2, 3, {0, 1, 2}} // R3: 2-3 questions, eligible for all
526 };
527
528 cout << "\n--- Finding Feasible Assignment ---" << endl;
529
530 auto result = design_survey(questions, respondents);
531
532 if (result.feasible)
533 {
534 cout << "\n*** Feasible Assignment Found! ***" << endl;
535
536 // Group by respondent
538 for (const auto& [r, q] : result.assignments)
540
541 cout << "\nAssignments:" << endl;
542 for (const auto& [r, qs] : resp_questions)
543 {
544 cout << " Respondent " << r << " answers: ";
545 for (size_t q : qs)
546 cout << "Q" << q << " ";
547 cout << endl;
548 }
549
550 // Verify question coverage
551 cout << "\nQuestion coverage:" << endl;
552 for (size_t q = 0; q < questions.size(); ++q)
553 {
554 int count = 0;
555 for (const auto& [r, qid] : result.assignments)
556 if (qid == q) count++;
557
558 cout << " Q" << q << ": " << count << " responses "
559 << "(need " << questions[q].min_responses << "-"
560 << questions[q].max_responses << ")" << endl;
561 }
562 }
563 else
564 {
565 cout << "\nNo feasible assignment exists!" << endl;
566 cout << "The constraints are too restrictive." << endl;
567 }
568}
569
570int main(int argc, char* argv[])
571{
572 cout << "=== Network Flow Applications ===" << endl;
573 cout << "Real-world problems solved with max-flow/min-cut\n" << endl;
574
575 if (has_flag(argc, argv, "--help"))
576 {
577 cout << "Usage: " << argv[0] << " [--project-selection] [--image-segmentation] "
578 "[--baseball-elimination] [--survey-design] [--help]\n";
579 cout << "\nIf no flags are given, all demos are executed.\n";
580 return 0;
581 }
582
583 const bool any_specific =
584 has_flag(argc, argv, "--project-selection") ||
585 has_flag(argc, argv, "--image-segmentation") ||
586 has_flag(argc, argv, "--baseball-elimination") ||
587 has_flag(argc, argv, "--survey-design");
588
589 if (!any_specific || has_flag(argc, argv, "--project-selection"))
591
592 if (!any_specific || has_flag(argc, argv, "--image-segmentation"))
594
595 if (!any_specific || has_flag(argc, argv, "--baseball-elimination"))
597
598 if (!any_specific || has_flag(argc, argv, "--survey-design"))
600
601 // Summary
602 cout << "\n" << string(60, '=') << endl;
603 cout << "Summary" << endl;
604 cout << string(60, '=') << endl;
605
606 cout << R"(
607These problems share a common structure:
608
6091. **Project Selection** (Max Closure)
610 - Model: Projects as nodes, dependencies as infinite edges
611 - Solution: Min s-t cut separates selected from rejected
612
6132. **Image Segmentation** (Graph Cuts)
614 - Model: Pixels as nodes, neighbor edges with smoothness cost
615 - Solution: Min cut optimally labels foreground/background
616
6173. **Baseball Elimination**
618 - Model: Game outcomes as flow through team vertices
619 - Solution: If max-flow < total games, team is eliminated
620
6214. **Survey Design** (Feasibility)
622 - Model: Bipartite matching with lower bounds
623 - Solution: Flow satisfies constraints if feasible
624
625Key Insight:
626 Many combinatorial problems reduce to max-flow/min-cut,
627 yielding polynomial-time algorithms for NP-hard looking problems!
628)" << endl;
629
630 return 0;
631}
int main()
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
BaseballEliminationResult check_baseball_elimination(const std::vector< Team > &teams, size_t team_idx)
Check if a team is mathematically eliminated from winning.
Definition net_apps.H:628
ProjectSelectionResult< Value_Type > solve_project_selection(const std::vector< Project< Value_Type > > &projects)
Solve project selection problem using max-flow.
Definition net_apps.H:457
SegmentationResult segment_image(size_t rows, size_t cols, const std::vector< std::vector< std::array< Value_Type, 2 > > > &data_cost, Value_Type smoothness)
Segment image using graph cuts.
Definition net_apps.H:800
SurveyDesignResult design_survey(const std::vector< SurveyQuestion > &questions, const std::vector< SurveyRespondent > &respondents)
Design survey assignment using network flow.
Definition net_apps.H:956
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
STL namespace.
Network flow applications.
void demo_baseball_elimination()
Demo 3: Baseball Elimination.
void demo_survey_design()
Demo 4: Survey Design.
void demo_image_segmentation()
Demo 2: Image Segmentation.
static bool has_flag(int argc, char *argv[], const char *flag)
void demo_project_selection()
Demo 1: Project Selection Problem.
Team information for baseball elimination.
Definition net_apps.H:573