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
62#ifndef NET_APPS_H
63#define NET_APPS_H
64
65#include <array>
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// CIRCULATION WITH DEMANDS
79//==============================================================================
80
84template <typename Flow_Type>
91
134template <class Net, class GetDemand, class GetLower, template <class> class Maxflow = Dinic_Maximum_Flow>
137{
138 using Node = typename Net::Node;
139 using Arc = typename Net::Arc;
140 using Flow_Type = typename Net::Flow_Type;
141
143
144 // Collect original nodes (before adding super nodes)
146 for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
147 original_nodes.append(it.get_curr());
148
149 // Store original capacities to restore later
151 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
152 {
153 Arc *arc = it.get_curr();
154 original_caps[arc] = arc->cap;
155 }
156
157 // Create super-source and super-sink for the transformed network
158 Node *super_source = net.insert_node();
159 Node *super_sink = net.insert_node();
160
161 // Track arcs we add so we can remove them later
163
164 // Calculate total positive ADJUSTED demand
165 // (This must be computed from adjusted demands, not original demands)
166 Flow_Type total_demand{0};
167
168 // Add edges from super-source/to super-sink based on adjusted demands
169 for (auto *v : original_nodes)
170 {
171 // Calculate adjusted demand: d'(v) = d(v) + l_out(v) - l_in(v)
172 // This comes from the circulation reduction with lower bounds:
173 // - For each arc (u,v) with lower bound l: the mandatory l units
174 // count as outflow from u and inflow to v.
175 // - d'(u) = d(u) + l (gains "debt" from mandatory outflow)
176 // - d'(v) = d(v) - l (satisfied by mandatory inflow)
178 for (typename Net::Node_Arc_Iterator ait(v); ait.has_curr(); ait.next_ne())
179 {
180 Arc *arc = ait.get_curr();
181 Flow_Type lb = get_lower(arc);
182 if (net.get_tgt_node(arc) == v)
183 lower_in += lb;
184 if (net.get_src_node(arc) == v)
185 lower_out += lb;
186 }
187
189
190 if (adjusted_demand > 0)
191 {
192 total_demand += adjusted_demand;
193 added_arcs.append(net.insert_arc(super_source, v, adjusted_demand));
194 }
195 else if (adjusted_demand < 0)
196 added_arcs.append(net.insert_arc(v, super_sink, -adjusted_demand));
197 }
198
199 // Trivial case: no adjusted demands means circulation with lower bounds is feasible
200 if (total_demand == Flow_Type{0})
201 {
202 result.feasible = true;
203 // Set all flows to their lower bounds
204 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
205 {
206 Arc *arc = it.get_curr();
207 if (original_caps.contains(arc))
208 result.flow[arc] = get_lower(arc);
209 }
210 // Cleanup: remove added arcs and nodes
211 for (Arc *arc : added_arcs)
212 net.remove_arc(arc);
213 net.remove_node(super_source);
214 net.remove_node(super_sink);
215 return result;
216 }
217
218 // Adjust arc capacities: cap' = cap - lower_bound
219 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
220 {
221 Arc *arc = it.get_curr();
222 Node *src = net.get_src_node(arc);
223 Node *tgt = net.get_tgt_node(arc);
224
225 // Skip super-source/sink arcs (they don't have lower bounds)
226 if (src == super_source or tgt == super_sink)
227 continue;
228
229 Flow_Type lb = get_lower(arc);
230 arc->cap -= lb;
231 }
232
233 // Ensure super_source is the ONLY source and super_sink is the ONLY sink.
234 // For the max-flow to correctly compute feasibility, we need paths from s* to t*.
235 //
236 // For original sinks (nodes with no outgoing arcs), flow arriving at them has
237 // nowhere to go. We add arcs to super_sink. The capacity should be the incoming
238 // capacity from ORIGINAL arcs only (not demand arcs), since we're measuring
239 // how much flow can reach this sink through the original network.
240 //
241 // For original sources (nodes with no incoming arcs), we add zero-capacity
242 // arcs just to make them non-sources in the network topology.
243 for (auto *v : original_nodes)
244 {
245 // Check if v is still a source (no incoming arcs)
246 if (net.get_in_degree(v) == 0)
247 added_arcs.append(net.insert_arc(super_source, v, Flow_Type{0}));
248
249 // Check if v is still a sink (no outgoing arcs): add arc to super_sink
250 // Compute incoming capacity from ORIGINAL arcs only
251 if (net.get_out_degree(v) == 0)
252 {
254 for (typename Net::Node_Arc_Iterator ait(v); ait.has_curr(); ait.next_ne())
255 if (Arc *arc = ait.get_curr(); net.get_tgt_node(arc) == v and original_caps.contains(arc))
256 in_cap_orig += arc->cap; // Use modified cap (original - lower)
257 added_arcs.append(net.insert_arc(v, super_sink, in_cap_orig));
258 }
259 }
260
261 // Solve max-flow on the transformed network
262 Flow_Type max_flow = Maxflow<Net>()(net);
263
264 result.feasible = (max_flow == total_demand);
265 result.excess_flow = max_flow;
266
267 // Compute actual circulation flow on original arcs.
268 // The max-flow determines feasibility but may route through auxiliary arcs.
269 // We need to compute flows on original arcs using flow conservation equations.
270 //
271 // For each original arc, start with lower bound and adjust based on demands.
272 // First, initialize flows to lower bounds.
273 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
274 {
275 Arc *arc = it.get_curr();
276 if (original_caps.contains(arc))
277 result.flow[arc] = get_lower(arc);
278 }
279
280 // If feasible, compute the actual circulation flows.
281 // For each node, we need: inflow - outflow = demand
282 // Use an iterative approach: repeatedly process nodes until all balances are satisfied.
283 if (result.feasible)
284 {
285 // Iterate until all nodes have correct flow balance
286 bool changed = true;
287 int max_iterations = original_nodes.size() * 2; // Safety limit
288 while (changed and max_iterations-- > 0)
289 {
290 changed = false;
291 for (auto *v : original_nodes)
292 {
293 // Compute current balance at v
295 for (typename Net::Node_Arc_Iterator ait(v); ait.has_curr(); ait.next_ne())
296 {
297 Arc *arc = ait.get_curr();
298 if (not original_caps.contains(arc))
299 continue;
300 if (net.get_tgt_node(arc) == v)
301 current_in += result.flow[arc];
302 if (net.get_src_node(arc) == v)
303 current_out += result.flow[arc];
304 }
305
306 // imbalance = (current_in - current_out) - demand
308
309 if (imbalance < Flow_Type{0})
310 {
311 // Node needs more inflow - increase flow on incoming arcs
313 for (typename Net::Node_Arc_Iterator ait(v); ait.has_curr(); ait.next_ne())
314 {
315 Arc *arc = ait.get_curr();
316 if (not original_caps.contains(arc))
317 continue;
318 if (net.get_tgt_node(arc) != v)
319 continue;
320
321 Flow_Type slack = original_caps[arc] - result.flow[arc];
323 if (increase > Flow_Type{0})
324 {
325 result.flow[arc] += increase;
326 deficit -= increase;
327 changed = true;
328 }
329 if (deficit <= Flow_Type{0})
330 break;
331 }
332 }
333 else if (imbalance > Flow_Type{0})
334 {
335 // Node has excess inflow - increase flow on outgoing arcs
336 Flow_Type excess = imbalance;
337 for (typename Net::Node_Arc_Iterator ait(v); ait.has_curr(); ait.next_ne())
338 {
339 Arc *arc = ait.get_curr();
340 if (not original_caps.contains(arc))
341 continue;
342 if (net.get_src_node(arc) != v)
343 continue;
344
345 Flow_Type slack = original_caps[arc] - result.flow[arc];
346 Flow_Type increase = (slack < excess) ? slack : excess;
347 if (increase > Flow_Type{0})
348 {
349 result.flow[arc] += increase;
350 excess -= increase;
351 changed = true;
352 }
353 if (excess <= Flow_Type{0})
354 break;
355 }
356 }
357 }
358 }
359 }
360
361 // Cleanup: restore original capacities and reset flows
362 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
363 {
364 Arc *arc = it.get_curr();
365 if (original_caps.contains(arc))
366 {
367 arc->cap = original_caps[arc];
368 arc->flow = Flow_Type{0}; // Reset flow
369 }
370 }
371
372 // Cleanup: remove added arcs (must be done before removing nodes)
373 for (Arc *arc : added_arcs)
374 net.remove_arc(arc);
375
376 // Cleanup: remove super nodes we created
377 net.remove_node(super_source);
378 net.remove_node(super_sink);
379
380 return result;
381}
382
383//==============================================================================
384// PROJECT SELECTION (MAX PROFIT / CLOSURE)
385//==============================================================================
386
390template <typename Value_Type>
392{
393 size_t id;
394 Value_Type profit;
395 std::vector<size_t> prerequisites;
396 std::string name;
397
398 Project(size_t id_, Value_Type profit_, const std::vector<size_t> &prereqs = {},
399 const std::string &name_ = "")
400 : id(id_), profit(profit_), prerequisites(prereqs), name(name_)
401 {}
402};
403
407template <typename Value_Type>
409{
410 Value_Type max_profit{0};
411 std::vector<size_t> selected;
412 Value_Type total_revenue{0};
413 Value_Type total_cost{0};
414};
415
449template <typename Value_Type>
451{
453 using Node = typename Net::Node;
454
456
457 if (projects.empty())
458 return result;
459
460 Net net;
461 const Value_Type INF = std::numeric_limits<Value_Type>::max() / 2;
462
463 // Create source and sink
464 Node *source = net.insert_node();
465 Node *sink = net.insert_node();
466
467 // Create project nodes
468 std::vector<Node *> project_nodes(projects.size());
469 for (size_t i = 0; i < projects.size(); ++i)
470 project_nodes[i] = net.insert_node();
471
472 // Connect based on profits
473 Value_Type sum_positive{0};
474
475 for (size_t i = 0; i < projects.size(); ++i)
476 {
477 Value_Type p = projects[i].profit;
478
479 // Source to all projects (capacity = profit if positive, 0 otherwise)
480 // This ensures all project nodes are not sources
481 Value_Type source_cap = (p > 0) ? p : Value_Type{0};
482 net.insert_arc(source, project_nodes[i], source_cap);
483 if (p > 0)
484 sum_positive += p;
485
486 // All projects connect to sink (cost projects with capacity = -profit,
487 // others with capacity 0 to ensure proper network structure)
488 Value_Type sink_cap = (p < 0) ? -p : Value_Type{0};
489 net.insert_arc(project_nodes[i], sink, sink_cap);
490
491 // Add prerequisite edges (infinite capacity)
492 for (size_t prereq : projects[i].prerequisites)
493 if (prereq < projects.size())
495 }
496
497 // Solve min-cut (via max-flow)
498 Value_Type min_cut = dinic_maximum_flow(net);
499
501
502 // Find selected projects (reachable from source in residual graph)
504
505 // BFS from source in residual graph
507 queue.put(source);
508 reachable.insert(source);
509
510 while (not queue.is_empty())
511 {
512 Node *u = queue.front();
513 queue.get();
514
515 for (typename Net::Node_Arc_Iterator it(u); it.has_curr(); it.next_ne())
516 {
517 auto arc = it.get_curr();
518 auto v = net.get_connected_node(arc, u);
519
520 if (reachable.contains(v))
521 continue;
522
523 // Check residual capacity
524 Value_Type residual;
525 if (net.get_src_node(arc) == u)
526 residual = arc->cap - arc->flow;
527 else
528 residual = arc->flow;
529
530 if (residual > Value_Type{0})
531 {
532 reachable.insert(v);
533 queue.put(v);
534 }
535 }
536 }
537
538 // Projects reachable from source are selected
539 for (size_t i = 0; i < projects.size(); ++i)
540 if (reachable.contains(project_nodes[i]))
541 {
542 result.selected.push_back(i);
543 if (projects[i].profit > 0)
544 result.total_revenue += projects[i].profit;
545 else
546 result.total_cost += -projects[i].profit;
547 }
548
549 return result;
550}
551
552//==============================================================================
553// BASEBALL ELIMINATION
554//==============================================================================
555
559struct Team
560{
561 std::string name;
562 int wins;
565 std::vector<int> against;
566
567 Team(const std::string &n = "", int w = 0, int l = 0, int r = 0)
568 : name(n), wins(w), losses(l), remaining(r)
569 {}
570};
571
576{
577 bool eliminated{false};
578 std::vector<size_t> certificate;
580};
581
616 size_t team_idx)
617{
619 using Node = Net::Node;
620
622
623 if (team_idx >= teams.size())
624 return result;
625
626 const Team &x = teams[team_idx];
627 result.max_possible_wins = x.wins + x.remaining;
628
629 // Trivial elimination check
630 for (size_t i = 0; i < teams.size(); ++i)
631 if (i != team_idx and teams[i].wins > result.max_possible_wins)
632 {
633 result.eliminated = true;
634 result.certificate.push_back(i);
635 return result;
636 }
637
638 Net net;
639
640 Node *source = net.insert_node();
641 Node *sink = net.insert_node();
642
643 // Create team nodes (excluding team x)
644 std::vector<Node *> team_nodes(teams.size(), nullptr);
645 for (size_t i = 0; i < teams.size(); ++i)
646 if (i != team_idx)
647 {
648 team_nodes[i] = net.insert_node();
649
650 // Team to sink: capacity = max wins x can have - current wins of i
651 if (int cap = result.max_possible_wins - teams[i].wins; cap > 0)
652 net.insert_arc(team_nodes[i], sink, cap);
653 }
654
655 // Create game nodes
656 int total_games = 0;
657 for (size_t i = 0; i < teams.size(); ++i)
658 {
659 if (i == team_idx)
660 continue;
661
662 for (size_t j = i + 1; j < teams.size(); ++j)
663 {
664 if (j == team_idx)
665 continue;
666
667 int games = teams[i].against[j];
668 if (games > 0)
669 {
670 constexpr int INF = 1000000;
672
673 Node *game_node = net.insert_node();
674 net.insert_arc(source, game_node, games);
675 net.insert_arc(game_node, team_nodes[i], INF);
676 net.insert_arc(game_node, team_nodes[j], INF);
677 }
678 }
679 }
680
681 // Ensure network has single source and sink
682 net.make_super_source();
683 net.make_super_sink();
684
685 const int max_flow = dinic_maximum_flow(net);
686
687 result.eliminated = (max_flow < total_games);
688
689 // If eliminated, find certificate (teams in source side of min-cut)
690 if (result.eliminated)
691 {
692 // BFS from source in residual graph
695 queue.put(source);
696 reachable.insert(source);
697
698 while (not queue.is_empty())
699 {
700 Node *u = queue.front();
701 queue.get();
702
703 for (Net::Node_Arc_Iterator it(u); it.has_curr(); it.next_ne())
704 {
705 const auto arc = it.get_curr();
706 auto v = net.get_connected_node(arc, u);
707
708 if (reachable.contains(v))
709 continue;
710
711 if (const int residual =
712 (net.get_src_node(arc) == u) ? (arc->cap - arc->flow) : arc->flow;
713 residual > 0)
714 {
715 reachable.insert(v);
716 queue.put(v);
717 }
718 }
719 }
720
721 for (size_t i = 0; i < teams.size(); ++i)
722 if (i != team_idx and team_nodes[i] != nullptr and reachable.contains(team_nodes[i]))
723 result.certificate.push_back(i);
724 }
725
726 return result;
727}
728
729//==============================================================================
730// IMAGE SEGMENTATION (BINARY LABELING)
731//==============================================================================
732
737{
738 std::vector<std::vector<int>> labels;
739 double energy{0};
740};
741
779template <typename Value_Type>
781 const std::vector<std::vector<std::array<Value_Type, 2>>> &data_cost,
782 Value_Type smoothness)
783{
785 using Node = typename Net::Node;
786
787 SegmentationResult result;
788 result.labels.resize(rows, std::vector<int>(cols, 0));
789
790 if (rows == 0 or cols == 0)
791 return result;
792
793 Net net;
794
795 // Create source (label 0) and sink (label 1)
796 Node *source = net.insert_node();
797 Node *sink = net.insert_node();
798
799 // Create pixel nodes
800 std::vector<std::vector<Node *>> pixels(rows, std::vector<Node *>(cols));
801 for (size_t i = 0; i < rows; ++i)
802 for (size_t j = 0; j < cols; ++j)
803 pixels[i][j] = net.insert_node();
804
805 // Add data term edges (standard graph cut model for binary labeling)
806 // See: Boykov, Kolmogorov "An Experimental Comparison of Min-Cut/Max-Flow Algorithms"
807 for (size_t i = 0; i < rows; ++i)
808 for (size_t j = 0; j < cols; ++j)
809 {
810 // Source to pixel: capacity = cost of background (label 0)
811 // If this arc is cut, pixel goes to sink side = background
812 net.insert_arc(source, pixels[i][j], data_cost[i][j][0]);
813
814 // Pixel to sink: capacity = cost of foreground (label 1)
815 // If this arc is cut, pixel stays on source side = foreground
816 net.insert_arc(pixels[i][j], sink, data_cost[i][j][1]);
817 }
818
819 // Add smoothness term edges (4-connected)
820 for (size_t i = 0; i < rows; ++i)
821 for (size_t j = 0; j < cols; ++j)
822 {
823 // Right neighbor
824 if (j + 1 < cols)
825 {
826 net.insert_arc(pixels[i][j], pixels[i][j + 1], smoothness);
827 net.insert_arc(pixels[i][j + 1], pixels[i][j], smoothness);
828 }
829
830 // Bottom neighbor
831 if (i + 1 < rows)
832 {
833 net.insert_arc(pixels[i][j], pixels[i + 1][j], smoothness);
834 net.insert_arc(pixels[i + 1][j], pixels[i][j], smoothness);
835 }
836 }
837
838 // Ensure network has single source and sink
839 net.make_super_source();
840 net.make_super_sink();
841
842 // Compute min-cut
843 Value_Type min_cut = dinic_maximum_flow(net);
844 result.energy = static_cast<double>(min_cut);
845
846 // Extract labels (BFS from source in residual graph)
847 DynSetTree<Node *> foreground; // Reachable = foreground (label 1)
848
850 queue.put(source);
851 foreground.insert(source);
852
853 while (not queue.is_empty())
854 {
855 Node *u = queue.front();
856 queue.get();
857
858 for (typename Net::Node_Arc_Iterator it(u); it.has_curr(); it.next_ne())
859 {
860 auto arc = it.get_curr();
861 auto v = net.get_connected_node(arc, u);
862
863 if (foreground.contains(v))
864 continue;
865
866 Value_Type residual = (net.get_src_node(arc) == u) ? (arc->cap - arc->flow) : arc->flow;
867
868 if (residual > Value_Type{0})
869 {
870 foreground.insert(v);
871 queue.put(v);
872 }
873 }
874 }
875
876 // Set labels
877 for (size_t i = 0; i < rows; ++i)
878 for (size_t j = 0; j < cols; ++j)
879 result.labels[i][j] = foreground.contains(pixels[i][j]) ? 1 : 0;
880
881 return result;
882}
883
884//==============================================================================
885// SURVEY DESIGN
886//==============================================================================
887
892{
893 size_t id;
896};
897
902{
903 size_t id;
906 std::vector<size_t> eligible_questions;
907};
908
913{
914 bool feasible{false};
915 std::vector<std::pair<size_t, size_t>> assignments;
916};
917
931inline SurveyDesignResult design_survey(const std::vector<SurveyQuestion> &questions,
932 const std::vector<SurveyRespondent> &respondents)
933{
935 using Node = Net::Node;
936
937 SurveyDesignResult result;
938
939 if (questions.empty() or respondents.empty())
940 return result;
941
942 Net net;
943
944 Node *source = net.insert_node();
945 Node *sink = net.insert_node();
946
947 // Create question nodes
948 std::vector<Node *> question_nodes(questions.size());
949 for (size_t i = 0; i < questions.size(); ++i)
950 {
951 question_nodes[i] = net.insert_node();
952
953 // Question to sink: [min, max] responses
954 // For feasibility check, use max capacity
955 net.insert_arc(question_nodes[i], sink, questions[i].max_responses);
956 }
957
958 // Create respondent nodes
959 std::vector<Node *> respondent_nodes(respondents.size());
960 for (size_t i = 0; i < respondents.size(); ++i)
961 {
962 respondent_nodes[i] = net.insert_node();
963
964 // Source to respondent: [min, max] questions
965 net.insert_arc(source, respondent_nodes[i], respondents[i].max_questions);
966
967 // Respondent to eligible questions
968 for (size_t q : respondents[i].eligible_questions)
969 if (q < questions.size())
971 }
972
973 // Ensure network has single source and sink
974 net.make_super_source();
975 net.make_super_sink();
976
977 // Compute max flow
979
980 // Check if minimum constraints are satisfied
981 result.feasible = true;
982
983 for (size_t i = 0; i < questions.size(); ++i)
984 {
985 int responses = 0;
986 for (Net::Node_Arc_Iterator it(question_nodes[i]); it.has_curr(); it.next_ne())
987 if (const auto arc = it.get_curr(); net.get_tgt_node(arc) == sink)
988 responses = arc->flow;
989
990 if (responses < questions[i].min_responses)
991 {
992 result.feasible = false;
993 break;
994 }
995 }
996
997 // Extract assignments
998 if (result.feasible)
999 for (size_t r = 0; r < respondents.size(); ++r)
1000 for (Net::Node_Arc_Iterator it(respondent_nodes[r]); it.has_curr(); it.next_ne())
1001 if (const auto arc = it.get_curr(); arc->flow > 0)
1002 {
1003 // Find which question this is
1004 const auto tgt = net.get_tgt_node(arc);
1005 for (size_t q = 0; q < questions.size(); ++q)
1006 if (question_nodes[q] == tgt)
1007 {
1008 result.assignments.push_back({r, q});
1009 break;
1010 }
1011 }
1012
1013 return result;
1014}
1015
1016} // namespace Aleph
1017
1018#endif // NET_APPS_H
WeightedDigraph::Node Node
WeightedDigraph::Arc Arc
long double w
Definition btreepic.C:153
size_t * rows
Definition ca-c-api.h:112
size_t cols
Definition ca-c-api.h:105
bool has_curr() const noexcept
Check if there is a current valid item.
Definition array_it.H:231
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.
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
Generic key-value map implemented on top of a binary search tree.
Dynamic set backed by balanced binary search trees with automatic memory management.
const size_t & size() const
Returns the cardinality of the set.
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
Filtered iterator on the nodes of a graph.
Definition tpl_graph.H:1207
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
Definition graph-dry.H:779
Node * get_connected_node(Arc *arc, Node *node) const noexcept
Return the adjacent node to node through arc.
Definition graph-dry.H:820
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
Definition graph-dry.H:785
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
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:615
Net::Flow_Type dinic_maximum_flow(Net &net)
Compute maximum flow using Dinic's algorithm.
and
Check uniqueness with explicit hash + equality functors.
ProjectSelectionResult< Value_Type > solve_project_selection(const std::vector< Project< Value_Type > > &projects)
Solve project selection problem using max-flow.
Definition net_apps.H:450
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:780
SurveyDesignResult design_survey(const std::vector< SurveyQuestion > &questions, const std::vector< SurveyRespondent > &respondents)
Design survey assignment using network flow.
Definition net_apps.H:931
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:135
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:1863
Filtered iterator on all the arcs of a graph.
Definition tpl_graph.H:1165
Result of baseball elimination check.
Definition net_apps.H:576
std::vector< size_t > certificate
Teams that form elimination certificate.
Definition net_apps.H:578
int max_possible_wins
Maximum wins team can achieve.
Definition net_apps.H:579
bool eliminated
Is the team mathematically eliminated?
Definition net_apps.H:577
Result of a circulation problem.
Definition net_apps.H:86
bool feasible
Is there a feasible circulation?
Definition net_apps.H:87
Flow_Type excess_flow
Flow needed to satisfy demands.
Definition net_apps.H:88
DynMapTree< void *, Flow_Type > flow
Flow on each edge (arc pointer -> flow)
Definition net_apps.H:89
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:676
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:704
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:409
Value_Type max_profit
Maximum achievable profit.
Definition net_apps.H:410
std::vector< size_t > selected
IDs of selected projects.
Definition net_apps.H:411
Value_Type total_cost
Sum of negative profits (costs)
Definition net_apps.H:413
Value_Type total_revenue
Sum of positive profits.
Definition net_apps.H:412
Project with profit and dependencies.
Definition net_apps.H:392
Value_Type profit
Profit (positive) or cost (negative)
Definition net_apps.H:394
size_t id
Unique project ID.
Definition net_apps.H:393
std::string name
Optional name.
Definition net_apps.H:396
std::vector< size_t > prerequisites
IDs of prerequisite projects.
Definition net_apps.H:395
Project(size_t id_, Value_Type profit_, const std::vector< size_t > &prereqs={}, const std::string &name_="")
Definition net_apps.H:398
Result of binary image segmentation.
Definition net_apps.H:737
std::vector< std::vector< int > > labels
0 or 1 for each pixel
Definition net_apps.H:738
double energy
Total energy of segmentation.
Definition net_apps.H:739
Result of survey design.
Definition net_apps.H:913
std::vector< std::pair< size_t, size_t > > assignments
(respondent, question)
Definition net_apps.H:915
Survey question with constraints.
Definition net_apps.H:892
int max_responses
Maximum responses accepted.
Definition net_apps.H:895
int min_responses
Minimum number of responses needed.
Definition net_apps.H:894
Survey respondent with constraints.
Definition net_apps.H:902
std::vector< size_t > eligible_questions
Questions this respondent can answer.
Definition net_apps.H:906
int min_questions
Minimum questions to answer.
Definition net_apps.H:904
int max_questions
Maximum questions can answer.
Definition net_apps.H:905
Team information for baseball elimination.
Definition net_apps.H:560
std::vector< int > against
Games remaining against each team.
Definition net_apps.H:565
Team(const std::string &n="", int w=0, int l=0, int r=0)
Definition net_apps.H:567
std::string name
Definition net_apps.H:561
int remaining
Games remaining.
Definition net_apps.H:564
gsl_rng * r
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