Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
net_apps.H
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
63#ifndef NET_APPS_H
64#define NET_APPS_H
65
66#include <vector>
67#include <string>
68#include <functional>
69#include <tpl_net.H>
70#include <tpl_maxflow.H>
71#include <tpl_netcost.H>
72#include <tpl_dynSetTree.H>
73#include <tpl_dynListQueue.H>
74
75namespace Aleph
76{
77
78//==============================================================================
79// CIRCULATION WITH DEMANDS
80//==============================================================================
81
85template <typename Flow_Type>
92
135template <class Net, class GetDemand, class GetLower,
136 template <class> class Maxflow = Dinic_Maximum_Flow>
139{
140 using Node = typename Net::Node;
141 using Arc = typename Net::Arc;
142 using Flow_Type = typename Net::Flow_Type;
143
145
146 // Collect original nodes (before adding super nodes)
148 for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
149 original_nodes.append(it.get_curr());
150
151 // Store original capacities to restore later
153 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
154 {
155 Arc* arc = it.get_curr();
156 original_caps[arc] = arc->cap;
157 }
158
159 // Create super-source and super-sink for the transformed network
160 Node* super_source = net.insert_node();
161 Node* super_sink = net.insert_node();
162
163 // Track arcs we add so we can remove them later
165
166 // Calculate total positive ADJUSTED demand
167 // (This must be computed from adjusted demands, not original demands)
168 Flow_Type total_demand{0};
169
170 // Add edges from super-source/to super-sink based on adjusted demands
171 for (auto* v : original_nodes)
172 {
173 // Calculate adjusted demand: d'(v) = d(v) + l_out(v) - l_in(v)
174 // This comes from the circulation reduction with lower bounds:
175 // - For each arc (u,v) with lower bound l: the mandatory l units
176 // count as outflow from u and inflow to v.
177 // - d'(u) = d(u) + l (gains "debt" from mandatory outflow)
178 // - d'(v) = d(v) - l (satisfied by mandatory inflow)
180 for (typename Net::Node_Arc_Iterator ait(v); ait.has_curr(); ait.next_ne())
181 {
182 Arc* arc = ait.get_curr();
183 Flow_Type lb = get_lower(arc);
184 if (net.get_tgt_node(arc) == v)
185 lower_in += lb;
186 if (net.get_src_node(arc) == v)
187 lower_out += lb;
188 }
189
191
192 if (adjusted_demand > 0)
193 {
194 total_demand += adjusted_demand;
195 added_arcs.append(net.insert_arc(super_source, v, adjusted_demand));
196 }
197 else if (adjusted_demand < 0)
198 added_arcs.append(net.insert_arc(v, super_sink, -adjusted_demand));
199 }
200
201 // Trivial case: no adjusted demands means circulation with lower bounds is feasible
202 if (total_demand == Flow_Type{0})
203 {
204 result.feasible = true;
205 // Set all flows to their lower bounds
206 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
207 {
208 Arc* arc = it.get_curr();
209 if (original_caps.contains(arc))
210 result.flow[arc] = get_lower(arc);
211 }
212 // Cleanup: remove added arcs and nodes
213 for (Arc* arc : added_arcs)
214 net.remove_arc(arc);
215 net.remove_node(super_source);
216 net.remove_node(super_sink);
217 return result;
218 }
219
220 // Adjust arc capacities: cap' = cap - lower_bound
221 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
222 {
223 Arc* arc = it.get_curr();
224 Node* src = net.get_src_node(arc);
225 Node* tgt = net.get_tgt_node(arc);
226
227 // Skip super-source/sink arcs (they don't have lower bounds)
228 if (src == super_source or tgt == super_sink)
229 continue;
230
231 Flow_Type lb = get_lower(arc);
232 arc->cap -= lb;
233 }
234
235 // Ensure super_source is the ONLY source and super_sink is the ONLY sink.
236 // For the max-flow to correctly compute feasibility, we need paths from s* to t*.
237 //
238 // For original sinks (nodes with no outgoing arcs), flow arriving at them has
239 // nowhere to go. We add arcs to super_sink. The capacity should be the incoming
240 // capacity from ORIGINAL arcs only (not demand arcs), since we're measuring
241 // how much flow can reach this sink through the original network.
242 //
243 // For original sources (nodes with no incoming arcs), we add zero-capacity
244 // arcs just to make them non-sources in the network topology.
245 for (auto* v : original_nodes)
246 {
247 // Check if v is still a source (no incoming arcs)
248 if (net.get_in_degree(v) == 0)
249 added_arcs.append(net.insert_arc(super_source, v, Flow_Type{0}));
250
251 // Check if v is still a sink (no outgoing arcs): add arc to super_sink
252 // Compute incoming capacity from ORIGINAL arcs only
253 if (net.get_out_degree(v) == 0)
254 {
256 for (typename Net::Node_Arc_Iterator ait(v); ait.has_curr(); ait.next_ne())
257 {
258 Arc* arc = ait.get_curr();
259 if (net.get_tgt_node(arc) == v and original_caps.contains(arc))
260 in_cap_orig += arc->cap; // Use modified cap (original - lower)
261 }
262 added_arcs.append(net.insert_arc(v, super_sink, in_cap_orig));
263 }
264 }
265
266 // Solve max-flow on the transformed network
267 Flow_Type max_flow = Maxflow<Net>()(net);
268
269 result.feasible = (max_flow == total_demand);
270 result.excess_flow = max_flow;
271
272 // Compute actual circulation flow on original arcs.
273 // The max-flow determines feasibility but may route through auxiliary arcs.
274 // We need to compute flows on original arcs using flow conservation equations.
275 //
276 // For each original arc, start with lower bound and adjust based on demands.
277 // First, initialize flows to lower bounds.
278 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
279 {
280 Arc* arc = it.get_curr();
281 if (original_caps.contains(arc))
282 result.flow[arc] = get_lower(arc);
283 }
284
285 // If feasible, compute the actual circulation flows.
286 // For each node, we need: inflow - outflow = demand
287 // Use an iterative approach: repeatedly process nodes until all balances are satisfied.
288 if (result.feasible)
289 {
290 // Iterate until all nodes have correct flow balance
291 bool changed = true;
292 int max_iterations = original_nodes.size() * 2; // Safety limit
293 while (changed and max_iterations-- > 0)
294 {
295 changed = false;
296 for (auto* v : original_nodes)
297 {
298 // Compute current balance at v
300 for (typename Net::Node_Arc_Iterator ait(v); ait.has_curr(); ait.next_ne())
301 {
302 Arc* arc = ait.get_curr();
303 if (not original_caps.contains(arc))
304 continue;
305 if (net.get_tgt_node(arc) == v)
306 current_in += result.flow[arc];
307 if (net.get_src_node(arc) == v)
308 current_out += result.flow[arc];
309 }
310
311 // imbalance = (current_in - current_out) - demand
313
314 if (imbalance < Flow_Type{0})
315 {
316 // Node needs more inflow - increase flow on incoming arcs
318 for (typename Net::Node_Arc_Iterator ait(v); ait.has_curr(); ait.next_ne())
319 {
320 Arc* arc = ait.get_curr();
321 if (not original_caps.contains(arc))
322 continue;
323 if (net.get_tgt_node(arc) != v)
324 continue;
325
326 Flow_Type slack = original_caps[arc] - result.flow[arc];
328 if (increase > Flow_Type{0})
329 {
330 result.flow[arc] += increase;
331 deficit -= increase;
332 changed = true;
333 }
334 if (deficit <= Flow_Type{0})
335 break;
336 }
337 }
338 else if (imbalance > Flow_Type{0})
339 {
340 // Node has excess inflow - increase flow on outgoing arcs
341 Flow_Type excess = imbalance;
342 for (typename Net::Node_Arc_Iterator ait(v); ait.has_curr(); ait.next_ne())
343 {
344 Arc* arc = ait.get_curr();
345 if (not original_caps.contains(arc))
346 continue;
347 if (net.get_src_node(arc) != v)
348 continue;
349
350 Flow_Type slack = original_caps[arc] - result.flow[arc];
351 Flow_Type increase = (slack < excess) ? slack : excess;
352 if (increase > Flow_Type{0})
353 {
354 result.flow[arc] += increase;
355 excess -= increase;
356 changed = true;
357 }
358 if (excess <= Flow_Type{0})
359 break;
360 }
361 }
362 }
363 }
364 }
365
366 // Cleanup: restore original capacities and reset flows
367 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
368 {
369 Arc* arc = it.get_curr();
370 if (original_caps.contains(arc))
371 {
372 arc->cap = original_caps[arc];
373 arc->flow = Flow_Type{0}; // Reset flow
374 }
375 }
376
377 // Cleanup: remove added arcs (must be done before removing nodes)
378 for (Arc* arc : added_arcs)
379 net.remove_arc(arc);
380
381 // Cleanup: remove super nodes we created
382 net.remove_node(super_source);
383 net.remove_node(super_sink);
384
385 return result;
386}
387
388
389//==============================================================================
390// PROJECT SELECTION (MAX PROFIT / CLOSURE)
391//==============================================================================
392
396template <typename Value_Type>
398{
399 size_t id;
400 Value_Type profit;
401 std::vector<size_t> prerequisites;
402 std::string name;
403
404 Project(size_t id_, Value_Type profit_,
405 const std::vector<size_t>& prereqs = {},
406 const std::string& name_ = "")
408};
409
413template <typename Value_Type>
415{
416 Value_Type max_profit{0};
417 std::vector<size_t> selected;
418 Value_Type total_revenue{0};
419 Value_Type total_cost{0};
420};
421
455template <typename Value_Type>
458{
461 using Node = typename Net::Node;
462
464
465 if (projects.empty())
466 return result;
467
468 Net net;
469 const Value_Type INF = std::numeric_limits<Value_Type>::max() / 2;
470
471 // Create source and sink
472 Node* source = net.insert_node();
473 Node* sink = net.insert_node();
474
475 // Create project nodes
476 std::vector<Node*> project_nodes(projects.size());
477 for (size_t i = 0; i < projects.size(); ++i)
478 project_nodes[i] = net.insert_node();
479
480 // Connect based on profits
481 Value_Type sum_positive{0};
482
483 for (size_t i = 0; i < projects.size(); ++i)
484 {
485 Value_Type p = projects[i].profit;
486
487 // Source to all projects (capacity = profit if positive, 0 otherwise)
488 // This ensures all project nodes are not sources
489 Value_Type source_cap = (p > 0) ? p : Value_Type{0};
490 net.insert_arc(source, project_nodes[i], source_cap);
491 if (p > 0)
492 sum_positive += p;
493
494 // All projects connect to sink (cost projects with capacity = -profit,
495 // others with capacity 0 to ensure proper network structure)
496 Value_Type sink_cap = (p < 0) ? -p : Value_Type{0};
497 net.insert_arc(project_nodes[i], sink, sink_cap);
498
499 // Add prerequisite edges (infinite capacity)
500 for (size_t prereq : projects[i].prerequisites)
501 {
502 if (prereq < projects.size())
504 }
505 }
506
507 // Solve min-cut (via max-flow)
508 Value_Type min_cut = dinic_maximum_flow(net);
509
511
512 // Find selected projects (reachable from source in residual graph)
514
515 // BFS from source in residual graph
517 queue.put(source);
518 reachable.insert(source);
519
520 while (not queue.is_empty())
521 {
522 Node* u = queue.front();
523 queue.get();
524
525 for (typename Net::Node_Arc_Iterator it(u); it.has_curr(); it.next_ne())
526 {
527 auto arc = it.get_curr();
528 auto v = net.get_connected_node(arc, u);
529
530 if (reachable.contains(v))
531 continue;
532
533 // Check residual capacity
534 Value_Type residual;
535 if (net.get_src_node(arc) == u)
536 residual = arc->cap - arc->flow;
537 else
538 residual = arc->flow;
539
540 if (residual > Value_Type{0})
541 {
542 reachable.insert(v);
543 queue.put(v);
544 }
545 }
546 }
547
548 // Projects reachable from source are selected
549 for (size_t i = 0; i < projects.size(); ++i)
550 {
551 if (reachable.contains(project_nodes[i]))
552 {
553 result.selected.push_back(i);
554 if (projects[i].profit > 0)
555 result.total_revenue += projects[i].profit;
556 else
557 result.total_cost += -projects[i].profit;
558 }
559 }
560
561 return result;
562}
563
564
565//==============================================================================
566// BASEBALL ELIMINATION
567//==============================================================================
568
572struct Team
573{
574 std::string name;
575 int wins;
578 std::vector<int> against;
579
580 Team(const std::string& n = "", int w = 0, int l = 0, int r = 0)
581 : name(n), wins(w), losses(l), remaining(r) {}
582};
583
588{
589 bool eliminated{false};
590 std::vector<size_t> certificate;
592};
593
628check_baseball_elimination(const std::vector<Team>& teams, size_t team_idx)
629{
631 using Node = Net::Node;
632
634
635 if (team_idx >= teams.size())
636 return result;
637
638 const Team& x = teams[team_idx];
639 result.max_possible_wins = x.wins + x.remaining;
640
641 // Trivial elimination check
642 for (size_t i = 0; i < teams.size(); ++i)
643 {
644 if (i != team_idx and teams[i].wins > result.max_possible_wins)
645 {
646 result.eliminated = true;
647 result.certificate.push_back(i);
648 return result;
649 }
650 }
651
652 Net net;
653 const int INF = 1000000;
654
655 Node* source = net.insert_node();
656 Node* sink = net.insert_node();
657
658 // Create team nodes (excluding team x)
659 std::vector<Node*> team_nodes(teams.size(), nullptr);
660 for (size_t i = 0; i < teams.size(); ++i)
661 {
662 if (i != team_idx)
663 {
664 team_nodes[i] = net.insert_node();
665
666 // Team to sink: capacity = max wins x can have - current wins of i
667 int cap = result.max_possible_wins - teams[i].wins;
668 if (cap > 0)
669 net.insert_arc(team_nodes[i], sink, cap);
670 }
671 }
672
673 // Create game nodes
674 int total_games = 0;
675 for (size_t i = 0; i < teams.size(); ++i)
676 {
677 if (i == team_idx)
678 continue;
679
680 for (size_t j = i + 1; j < teams.size(); ++j)
681 {
682 if (j == team_idx)
683 continue;
684
685 int games = teams[i].against[j];
686 if (games > 0)
687 {
689
690 Node* game_node = net.insert_node();
691 net.insert_arc(source, game_node, games);
694 }
695 }
696 }
697
698 // Ensure network has single source and sink
699 net.make_super_source();
700 net.make_super_sink();
701
702 int max_flow = dinic_maximum_flow(net);
703
704 result.eliminated = (max_flow < total_games);
705
706 // If eliminated, find certificate (teams in source side of min-cut)
707 if (result.eliminated)
708 {
709 // BFS from source in residual graph
712 queue.put(source);
713 reachable.insert(source);
714
715 while (not queue.is_empty())
716 {
717 Node* u = queue.front();
718 queue.get();
719
720 for (Net::Node_Arc_Iterator it(u); it.has_curr(); it.next_ne())
721 {
722 auto arc = it.get_curr();
723 auto v = net.get_connected_node(arc, u);
724
725 if (reachable.contains(v))
726 continue;
727
728 int residual = (net.get_src_node(arc) == u) ?
729 (arc->cap - arc->flow) : arc->flow;
730
731 if (residual > 0)
732 {
733 reachable.insert(v);
734 queue.put(v);
735 }
736 }
737 }
738
739 for (size_t i = 0; i < teams.size(); ++i)
740 if (i != team_idx and team_nodes[i] != nullptr and
741 reachable.contains(team_nodes[i]))
742 result.certificate.push_back(i);
743 }
744
745 return result;
746}
747
748
749//==============================================================================
750// IMAGE SEGMENTATION (BINARY LABELING)
751//==============================================================================
752
757{
758 std::vector<std::vector<int>> labels;
759 double energy{0};
760};
761
799template <typename Value_Type>
801 size_t rows, size_t cols,
802 const std::vector<std::vector<std::array<Value_Type, 2>>>& data_cost,
803 Value_Type smoothness)
804{
807 using Node = typename Net::Node;
808
809 SegmentationResult result;
810 result.labels.resize(rows, std::vector<int>(cols, 0));
811
812 if (rows == 0 or cols == 0)
813 return result;
814
815 Net net;
816
817 // Create source (label 0) and sink (label 1)
818 Node* source = net.insert_node();
819 Node* sink = net.insert_node();
820
821 // Create pixel nodes
822 std::vector<std::vector<Node*>> pixels(rows, std::vector<Node*>(cols));
823 for (size_t i = 0; i < rows; ++i)
824 for (size_t j = 0; j < cols; ++j)
825 pixels[i][j] = net.insert_node();
826
827 // Add data term edges (standard graph cut model for binary labeling)
828 // See: Boykov, Kolmogorov "An Experimental Comparison of Min-Cut/Max-Flow Algorithms"
829 for (size_t i = 0; i < rows; ++i)
830 for (size_t j = 0; j < cols; ++j)
831 {
832 // Source to pixel: capacity = cost of background (label 0)
833 // If this arc is cut, pixel goes to sink side = background
834 net.insert_arc(source, pixels[i][j], data_cost[i][j][0]);
835
836 // Pixel to sink: capacity = cost of foreground (label 1)
837 // If this arc is cut, pixel stays on source side = foreground
838 net.insert_arc(pixels[i][j], sink, data_cost[i][j][1]);
839 }
840
841 // Add smoothness term edges (4-connected)
842 for (size_t i = 0; i < rows; ++i)
843 for (size_t j = 0; j < cols; ++j)
844 {
845 // Right neighbor
846 if (j + 1 < cols)
847 {
848 net.insert_arc(pixels[i][j], pixels[i][j+1], smoothness);
849 net.insert_arc(pixels[i][j+1], pixels[i][j], smoothness);
850 }
851
852 // Bottom neighbor
853 if (i + 1 < rows)
854 {
855 net.insert_arc(pixels[i][j], pixels[i+1][j], smoothness);
856 net.insert_arc(pixels[i+1][j], pixels[i][j], smoothness);
857 }
858 }
859
860 // Ensure network has single source and sink
861 net.make_super_source();
862 net.make_super_sink();
863
864 // Compute min-cut
865 Value_Type min_cut = dinic_maximum_flow(net);
866 result.energy = static_cast<double>(min_cut);
867
868 // Extract labels (BFS from source in residual graph)
869 DynSetTree<Node*> foreground; // Reachable = foreground (label 1)
870
872 queue.put(source);
873 foreground.insert(source);
874
875 while (not queue.is_empty())
876 {
877 Node* u = queue.front();
878 queue.get();
879
880 for (typename Net::Node_Arc_Iterator it(u); it.has_curr(); it.next_ne())
881 {
882 auto arc = it.get_curr();
883 auto v = net.get_connected_node(arc, u);
884
885 if (foreground.contains(v))
886 continue;
887
888 Value_Type residual = (net.get_src_node(arc) == u) ?
889 (arc->cap - arc->flow) : arc->flow;
890
891 if (residual > Value_Type{0})
892 {
894 queue.put(v);
895 }
896 }
897 }
898
899 // Set labels
900 for (size_t i = 0; i < rows; ++i)
901 for (size_t j = 0; j < cols; ++j)
902 result.labels[i][j] = foreground.contains(pixels[i][j]) ? 1 : 0;
903
904 return result;
905}
906
907
908//==============================================================================
909// SURVEY DESIGN
910//==============================================================================
911
916{
917 size_t id;
920};
921
926{
927 size_t id;
930 std::vector<size_t> eligible_questions;
931};
932
937{
938 bool feasible{false};
939 std::vector<std::pair<size_t, size_t>> assignments;
940};
941
956design_survey(const std::vector<SurveyQuestion>& questions,
957 const std::vector<SurveyRespondent>& respondents)
958{
960 using Node = Net::Node;
961
962 SurveyDesignResult result;
963
965 return result;
966
967 Net net;
968
969 Node* source = net.insert_node();
970 Node* sink = net.insert_node();
971
972 // Create question nodes
973 std::vector<Node*> question_nodes(questions.size());
974 for (size_t i = 0; i < questions.size(); ++i)
975 {
976 question_nodes[i] = net.insert_node();
977
978 // Question to sink: [min, max] responses
979 // For feasibility check, use max capacity
980 net.insert_arc(question_nodes[i], sink, questions[i].max_responses);
981 }
982
983 // Create respondent nodes
984 std::vector<Node*> respondent_nodes(respondents.size());
985 for (size_t i = 0; i < respondents.size(); ++i)
986 {
987 respondent_nodes[i] = net.insert_node();
988
989 // Source to respondent: [min, max] questions
990 net.insert_arc(source, respondent_nodes[i], respondents[i].max_questions);
991
992 // Respondent to eligible questions
993 for (size_t q : respondents[i].eligible_questions)
994 if (q < questions.size())
996 }
997
998 // Ensure network has single source and sink
999 net.make_super_source();
1000 net.make_super_sink();
1001
1002 // Compute max flow
1003 dinic_maximum_flow(net);
1004
1005 // Check if minimum constraints are satisfied
1006 result.feasible = true;
1007
1008 for (size_t i = 0; i < questions.size(); ++i)
1009 {
1010 int responses = 0;
1012 it.next_ne())
1013 {
1014 auto arc = it.get_curr();
1015 if (net.get_tgt_node(arc) == sink)
1016 responses = arc->flow;
1017 }
1018
1019 if (responses < questions[i].min_responses)
1020 {
1021 result.feasible = false;
1022 break;
1023 }
1024 }
1025
1026 // Extract assignments
1027 if (result.feasible)
1028 {
1029 for (size_t r = 0; r < respondents.size(); ++r)
1030 {
1032 it.has_curr(); it.next_ne())
1033 {
1034 auto arc = it.get_curr();
1035 if (arc->flow > 0)
1036 {
1037 // Find which question this is
1038 auto tgt = net.get_tgt_node(arc);
1039 for (size_t q = 0; q < questions.size(); ++q)
1040 if (question_nodes[q] == tgt)
1041 {
1042 result.assignments.push_back({r, q});
1043 break;
1044 }
1045 }
1046 }
1047 }
1048 }
1049
1050 return result;
1051}
1052
1053} // namespace Aleph
1054
1055#endif // NET_APPS_H
WeightedDigraph::Node Node
WeightedDigraph::Arc Arc
long double w
Definition btreepic.C:153
bool has_curr() const noexcept
Check if there is a current valid item.
Definition array_it.H:219
Dynamic queue of elements of generic type T based on single linked list.
T & put(const T &data)
The type of element.
T get()
Remove the oldest item of the queue.
T & front()
Return a modifiable reference to the oldest item in the queue.
bool is_empty() const noexcept
Return true if this is empty.
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
void empty() noexcept
empty the list
Definition htlist.H:1689
Generic key-value map implemented on top of a binary search tree.
Dynamic set backed by balanced binary search trees with automatic memory management.
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
Filtered iterator on the nodes of a graph.
Definition tpl_graph.H:1206
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
Definition graph-dry.H:731
Node * get_connected_node(Arc *arc, Node *node) const noexcept
Return the adjacent node to node through arc.
Definition graph-dry.H:772
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
Definition graph-dry.H:737
Net_Graph< Net_Node< string >, Net_Arc< Empty_Class, FlowType > > Net
double Flow_Type
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
Net::Flow_Type dinic_maximum_flow(Net &net)
Compute maximum flow using Dinic's algorithm.
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
CirculationResult< typename Net::Flow_Type > solve_circulation(Net &net, GetDemand get_demand, GetLower get_lower)
Solve a circulation problem with demands.
Definition net_apps.H:138
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.
Definition tpl_net.H:1864
DynList< T > maps(const C &c, Op op)
Classic map operation.
Filtered iterator on all the arcs of a graph.
Definition tpl_graph.H:1164
Result of baseball elimination check.
Definition net_apps.H:588
std::vector< size_t > certificate
Teams that form elimination certificate.
Definition net_apps.H:590
int max_possible_wins
Maximum wins team can achieve.
Definition net_apps.H:591
bool eliminated
Is the team mathematically eliminated?
Definition net_apps.H:589
Result of a circulation problem.
Definition net_apps.H:87
bool feasible
Is there a feasible circulation?
Definition net_apps.H:88
Flow_Type excess_flow
Flow needed to satisfy demands.
Definition net_apps.H:89
DynMapTree< void *, Flow_Type > flow
Flow on each edge (arc pointer -> flow)
Definition net_apps.H:90
Functor wrapper for Dinic's algorithm.
Arc of a flow network implemented with adjacency lists.
Definition tpl_net.H:115
Flow network implemented with adjacency lists.
Definition tpl_net.H:261
Node * insert_node(const Node_Type &node_info)
Insert a new node by copying node_info.
Definition tpl_net.H:559
void remove_arc(Arc *arc) override
Remove arc arc from the network.
Definition tpl_net.H:677
void make_super_source()
Convert a multi-source network into a single super-source network.
Definition tpl_net.H:458
void make_super_sink()
Convert a multi-sink network into a single super-sink network.
Definition tpl_net.H:493
size_t get_out_degree(Node *p) const noexcept
Return the out-degree of p (number of outgoing arcs).
Definition tpl_net.H:339
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.
Definition tpl_net.H:607
ArcT Arc
Arc type.
Definition tpl_net.H:272
typename Arc::Flow_Type Flow_Type
Capacity/flow numeric type.
Definition tpl_net.H:278
void remove_node(Node *p) noexcept override
Remove node p and all its arcs from the network.
Definition tpl_net.H:705
NodeT Node
Node type.
Definition tpl_net.H:275
size_t get_in_degree(Node *p) const noexcept
Return the in-degree of p (number of incoming arcs).
Definition tpl_net.H:333
Result of project selection.
Definition net_apps.H:415
Value_Type max_profit
Maximum achievable profit.
Definition net_apps.H:416
std::vector< size_t > selected
IDs of selected projects.
Definition net_apps.H:417
Value_Type total_cost
Sum of negative profits (costs)
Definition net_apps.H:419
Value_Type total_revenue
Sum of positive profits.
Definition net_apps.H:418
Project with profit and dependencies.
Definition net_apps.H:398
Value_Type profit
Profit (positive) or cost (negative)
Definition net_apps.H:400
size_t id
Unique project ID.
Definition net_apps.H:399
std::string name
Optional name.
Definition net_apps.H:402
std::vector< size_t > prerequisites
IDs of prerequisite projects.
Definition net_apps.H:401
Project(size_t id_, Value_Type profit_, const std::vector< size_t > &prereqs={}, const std::string &name_="")
Definition net_apps.H:404
Result of binary image segmentation.
Definition net_apps.H:757
std::vector< std::vector< int > > labels
0 or 1 for each pixel
Definition net_apps.H:758
double energy
Total energy of segmentation.
Definition net_apps.H:759
Result of survey design.
Definition net_apps.H:937
std::vector< std::pair< size_t, size_t > > assignments
(respondent, question)
Definition net_apps.H:939
Survey question with constraints.
Definition net_apps.H:916
int max_responses
Maximum responses accepted.
Definition net_apps.H:919
int min_responses
Minimum number of responses needed.
Definition net_apps.H:918
Survey respondent with constraints.
Definition net_apps.H:926
std::vector< size_t > eligible_questions
Questions this respondent can answer.
Definition net_apps.H:930
int min_questions
Minimum questions to answer.
Definition net_apps.H:928
int max_questions
Maximum questions can answer.
Definition net_apps.H:929
Team information for baseball elimination.
Definition net_apps.H:573
std::vector< int > against
Games remaining against each team.
Definition net_apps.H:578
Team(const std::string &n="", int w=0, int l=0, int r=0)
Definition net_apps.H:580
std::string name
Definition net_apps.H:574
int remaining
Games remaining.
Definition net_apps.H:577
Dynamic queue implementation based on linked lists.
Dynamic set implementations based on balanced binary search trees.
Advanced maximum flow algorithms.
Network flow graph structures.
Maximum flow minimum cost network algorithms.
DynList< int > l