Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
net_utils.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
78#ifndef NET_UTILS_H
79#define NET_UTILS_H
80
81#include <fstream>
82#include <sstream>
83#include <random>
84#include <chrono>
85#include <iomanip>
86#include <tpl_net.H>
87#include <tpl_netcost.H>
88#include <tpl_dynMapTree.H>
89
90namespace Aleph
91{
92
93//==============================================================================
94// NETWORK GENERATORS
95//==============================================================================
96
101{
102 size_t num_nodes = 10;
103 size_t num_arcs = 20;
104 double min_capacity = 1.0;
105 double max_capacity = 100.0;
106 double min_cost = 0.0;
107 double max_cost = 10.0;
108 bool ensure_connected = true;
109 unsigned seed = 0;
110};
111
133template <class Net>
135{
136 using Node = typename Net::Node;
137 using Flow_Type = typename Net::Flow_Type;
138
139 Net net;
140
141 // Initialize RNG
142 unsigned seed = params.seed;
143 if (seed == 0)
144 seed = static_cast<unsigned>(
145 std::chrono::system_clock::now().time_since_epoch().count());
146
147 std::mt19937 gen(seed);
148 std::uniform_real_distribution<double> cap_dist(params.min_capacity,
149 params.max_capacity);
150 std::uniform_int_distribution<size_t> node_dist(0, params.num_nodes - 1);
151
152 // Create nodes
153 std::vector<Node*> nodes(params.num_nodes);
154 for (size_t i = 0; i < params.num_nodes; ++i)
155 nodes[i] = net.insert_node();
156
157 // Set source and sink
158 // Sources and sinks are detected automatically by Net_Graph
159 // based on which nodes have no incoming/outgoing arcs
160
161 // Ensure connectivity: create a path from source to sink
162 if (params.ensure_connected)
163 {
164 for (size_t i = 0; i < params.num_nodes - 1; ++i)
165 {
166 Flow_Type cap = static_cast<Flow_Type>(cap_dist(gen));
167 net.insert_arc(nodes[i], nodes[i + 1], cap);
168 }
169 }
170
171 // Add random arcs
172 size_t arcs_to_add = params.num_arcs;
173 if (params.ensure_connected)
174 arcs_to_add -= (params.num_nodes - 1);
175
176 for (size_t i = 0; i < arcs_to_add; ++i)
177 {
178 size_t src = node_dist(gen);
179 size_t tgt = node_dist(gen);
180
181 // Avoid self-loops
182 if (src == tgt)
183 {
184 tgt = (tgt + 1) % params.num_nodes;
185 }
186
187 Flow_Type cap = static_cast<Flow_Type>(cap_dist(gen));
188 net.insert_arc(nodes[src], nodes[tgt], cap);
189 }
190
191 return net;
192}
193
206template <class Net>
207Net generate_random_network(size_t num_nodes, size_t num_arcs,
208 double min_cap = 1.0, double max_cap = 100.0,
209 unsigned seed = 0)
210{
212 params.num_nodes = num_nodes;
213 params.num_arcs = num_arcs;
214 params.min_capacity = min_cap;
215 params.max_capacity = max_cap;
216 params.seed = seed;
218}
219
243template <class Net>
244Net generate_grid_network(size_t rows, size_t cols,
245 typename Net::Flow_Type capacity,
246 bool bidirectional = true)
247{
248 using Node = typename Net::Node;
249
250 Net net;
251 std::vector<std::vector<Node*>> nodes(rows, std::vector<Node*>(cols));
252
253 // Create nodes
254 for (size_t i = 0; i < rows; ++i)
255 for (size_t j = 0; j < cols; ++j)
256 nodes[i][j] = net.insert_node();
257
258 // Create horizontal arcs
259 for (size_t i = 0; i < rows; ++i)
260 for (size_t j = 0; j < cols - 1; ++j)
261 {
262 net.insert_arc(nodes[i][j], nodes[i][j+1], capacity);
263 if (bidirectional)
264 net.insert_arc(nodes[i][j+1], nodes[i][j], capacity);
265 }
266
267 // Create vertical arcs
268 for (size_t i = 0; i < rows - 1; ++i)
269 for (size_t j = 0; j < cols; ++j)
270 {
271 net.insert_arc(nodes[i][j], nodes[i+1][j], capacity);
272 if (bidirectional)
273 net.insert_arc(nodes[i+1][j], nodes[i][j], capacity);
274 }
275
276 // Source (top-left) and sink (bottom-right) are detected automatically
277 // since nodes[0][0] has no incoming arcs and nodes[rows-1][cols-1] has no outgoing arcs
278
279 return net;
280}
281
300template <class Net>
301Net generate_bipartite_network(size_t left_size, size_t right_size,
302 double edge_prob = 0.5,
303 unsigned seed = 0)
304{
305 using Node = typename Net::Node;
306 using Flow_Type = typename Net::Flow_Type;
307
308 Net net;
309
310 if (seed == 0)
311 seed = static_cast<unsigned>(
312 std::chrono::system_clock::now().time_since_epoch().count());
313
314 std::mt19937 gen(seed);
315 std::uniform_real_distribution<double> prob_dist(0.0, 1.0);
316
317 // Create source and sink
318 Node* source = net.insert_node();
319 Node* sink = net.insert_node();
320
321 // Create left nodes
322 std::vector<Node*> left_nodes(left_size);
323 for (size_t i = 0; i < left_size; ++i)
324 {
325 left_nodes[i] = net.insert_node();
326 net.insert_arc(source, left_nodes[i], Flow_Type{1});
327 }
328
329 // Create right nodes
330 std::vector<Node*> right_nodes(right_size);
331 for (size_t i = 0; i < right_size; ++i)
332 {
333 right_nodes[i] = net.insert_node();
334 net.insert_arc(right_nodes[i], sink, Flow_Type{1});
335 }
336
337 // Create random edges between left and right
338 for (size_t i = 0; i < left_size; ++i)
339 for (size_t j = 0; j < right_size; ++j)
340 if (prob_dist(gen) < edge_prob)
342
343 // Source and sink are detected automatically
344
345 return net;
346}
347
362template <class Net>
363Net generate_layered_network(const std::vector<size_t>& layer_sizes,
364 typename Net::Flow_Type capacity,
365 double edge_prob = 0.5,
366 unsigned seed = 0)
367{
368 using Node = typename Net::Node;
369
370 Net net;
371
372 if (layer_sizes.size() < 2)
373 return net;
374
375 if (seed == 0)
376 seed = static_cast<unsigned>(
377 std::chrono::system_clock::now().time_since_epoch().count());
378
379 std::mt19937 gen(seed);
380 std::uniform_real_distribution<double> prob_dist(0.0, 1.0);
381
382 // Create nodes for each layer
383 std::vector<std::vector<Node*>> layers(layer_sizes.size());
384 for (size_t l = 0; l < layer_sizes.size(); ++l)
385 {
386 layers[l].resize(layer_sizes[l]);
387 for (size_t i = 0; i < layer_sizes[l]; ++i)
388 layers[l][i] = net.insert_node();
389 }
390
391 // Connect adjacent layers
392 for (size_t l = 0; l < layer_sizes.size() - 1; ++l)
393 {
394 for (size_t i = 0; i < layers[l].size(); ++i)
395 {
396 bool connected = false;
397 for (size_t j = 0; j < layers[l+1].size(); ++j)
398 if (prob_dist(gen) < edge_prob)
399 {
400 net.insert_arc(layers[l][i], layers[l+1][j], capacity);
401 connected = true;
402 }
403
404 // Ensure at least one connection
405 if (not connected and not layers[l+1].empty())
406 {
407 size_t j = gen() % layers[l+1].size();
408 net.insert_arc(layers[l][i], layers[l+1][j], capacity);
409 }
410 }
411 }
412
413 // Source and sink are detected automatically
414
415 return net;
416}
417
418
419//==============================================================================
420// DOT/GRAPHVIZ EXPORT
421//==============================================================================
422
427{
428 bool show_flow = true;
429 bool show_capacity = true;
430 bool show_cost = false;
432 bool highlight_empty = false;
433 bool use_colors = true;
434 std::string graph_name = "Network";
435 std::string source_color = "green";
436 std::string sink_color = "red";
437 std::string saturated_color = "blue";
438 std::string empty_color = "gray";
439};
440
461template <class Net>
462void export_network_to_dot(const Net& net, const std::string& filename,
464{
465 using Node = typename Net::Node;
466
467 std::ofstream out(filename);
468 if (not out)
469 return;
470
471 // Build node ID map
473 size_t id = 0;
474 for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
475 node_ids[it.get_curr()] = id++;
476
477 out << "digraph " << options.graph_name << " {\n";
478 out << " rankdir=LR;\n";
479 out << " node [shape=circle];\n";
480
481 // Export nodes
482 for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
483 {
484 Node* p = it.get_curr();
485 out << " " << node_ids[p];
486
487 std::string color;
488 if (net.is_single_source() and p == net.get_source())
489 color = options.source_color;
490 else if (net.is_single_sink() and p == net.get_sink())
491 color = options.sink_color;
492
493 if (not color.empty() and options.use_colors)
494 out << " [style=filled, fillcolor=" << color << "]";
495
496 out << ";\n";
497 }
498
499 // Export arcs
500 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
501 {
502 auto arc = it.get_curr();
503 Node* src = net.get_src_node(arc);
504 Node* tgt = net.get_tgt_node(arc);
505
506 out << " " << node_ids[src] << " -> " << node_ids[tgt];
507
508 // Build label
509 std::ostringstream label;
510 if (options.show_flow or options.show_capacity)
511 {
512 label << "\"";
513 if (options.show_flow)
514 label << arc->flow;
515 if (options.show_flow and options.show_capacity)
516 label << "/";
517 if (options.show_capacity)
518 label << arc->cap;
519 label << "\"";
520 }
521
522 // Build style
523 std::string color;
524 if (options.use_colors)
525 {
526 if (options.highlight_saturated and arc->flow == arc->cap)
527 color = options.saturated_color;
528 else if (options.highlight_empty and arc->flow == 0)
529 color = options.empty_color;
530 }
531
532 out << " [";
533 if (not label.str().empty())
534 out << "label=" << label.str();
535 if (not color.empty())
536 {
537 if (not label.str().empty())
538 out << ", ";
539 out << "color=" << color;
540 }
541 out << "];\n";
542 }
543
544 out << "}\n";
545}
546
556template <class Net>
557std::string network_to_dot_string(const Net& net,
559{
560 using Node = typename Net::Node;
561
562 std::ostringstream out;
563
564 // Build node ID map
566 size_t id = 0;
567 for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
568 node_ids[it.get_curr()] = id++;
569
570 out << "digraph " << options.graph_name << " {\n";
571 out << " rankdir=LR;\n";
572 out << " node [shape=circle];\n";
573
574 // Export nodes
575 for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
576 {
577 Node* p = it.get_curr();
578 out << " " << node_ids[p];
579
580 std::string color;
581 if (net.is_single_source() and p == net.get_source())
582 color = options.source_color;
583 else if (net.is_single_sink() and p == net.get_sink())
584 color = options.sink_color;
585
586 if (not color.empty() and options.use_colors)
587 out << " [style=filled, fillcolor=" << color << "]";
588
589 out << ";\n";
590 }
591
592 // Export arcs
593 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
594 {
595 auto arc = it.get_curr();
596 Node* src = net.get_src_node(arc);
597 Node* tgt = net.get_tgt_node(arc);
598
599 out << " " << node_ids[src] << " -> " << node_ids[tgt];
600
601 std::ostringstream label;
602 if (options.show_flow or options.show_capacity)
603 {
604 label << "\"";
605 if (options.show_flow)
606 label << arc->flow;
607 if (options.show_flow and options.show_capacity)
608 label << "/";
609 if (options.show_capacity)
610 label << arc->cap;
611 label << "\"";
612 }
613
614 std::string color;
615 if (options.use_colors)
616 {
617 if (options.highlight_saturated and arc->flow == arc->cap)
618 color = options.saturated_color;
619 else if (options.highlight_empty and arc->flow == 0)
620 color = options.empty_color;
621 }
622
623 out << " [";
624 if (not label.str().empty())
625 out << "label=" << label.str();
626 if (not color.empty())
627 {
628 if (not label.str().empty())
629 out << ", ";
630 out << "color=" << color;
631 }
632 out << "];\n";
633 }
634
635 out << "}\n";
636
637 return out.str();
638}
639
640
641//==============================================================================
642// JSON SERIALIZATION
643//==============================================================================
644
671template <class Net>
672void export_network_to_json(const Net& net, const std::string& filename)
673{
674 using Node = typename Net::Node;
675
676 std::ofstream out(filename);
677 if (not out)
678 return;
679
680 // Build node ID map
682 size_t id = 0;
683 for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
684 node_ids[it.get_curr()] = id++;
685
686 out << "{\n";
687
688 // Nodes
689 out << " \"num_nodes\": " << net.vsize() << ",\n";
690 out << " \"num_arcs\": " << net.esize() << ",\n";
691
692 // Source and sink
693 if (net.is_single_source())
694 out << " \"source\": " << node_ids[net.get_source()] << ",\n";
695 if (net.is_single_sink())
696 out << " \"sink\": " << node_ids[net.get_sink()] << ",\n";
697
698 // Arcs
699 out << " \"arcs\": [\n";
700 bool first = true;
701 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
702 {
703 if (not first)
704 out << ",\n";
705 first = false;
706
707 auto arc = it.get_curr();
708 out << " {"
709 << "\"src\": " << node_ids[net.get_src_node(arc)] << ", "
710 << "\"tgt\": " << node_ids[net.get_tgt_node(arc)] << ", "
711 << "\"cap\": " << arc->cap << ", "
712 << "\"flow\": " << arc->flow
713 << "}";
714 }
715 out << "\n ]\n";
716 out << "}\n";
717}
718
727template <class Net>
728std::string network_to_json_string(const Net& net)
729{
730 using Node = typename Net::Node;
731
732 std::ostringstream out;
733
734 // Build node ID map
736 size_t id = 0;
737 for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
738 node_ids[it.get_curr()] = id++;
739
740 out << "{\n";
741 out << " \"num_nodes\": " << net.vsize() << ",\n";
742 out << " \"num_arcs\": " << net.esize() << ",\n";
743
744 if (net.is_single_source())
745 out << " \"source\": " << node_ids[net.get_source()] << ",\n";
746 if (net.is_single_sink())
747 out << " \"sink\": " << node_ids[net.get_sink()] << ",\n";
748
749 out << " \"arcs\": [\n";
750 bool first = true;
751 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
752 {
753 if (not first)
754 out << ",\n";
755 first = false;
756
757 auto arc = it.get_curr();
758 out << " {"
759 << "\"src\": " << node_ids[net.get_src_node(arc)] << ", "
760 << "\"tgt\": " << node_ids[net.get_tgt_node(arc)] << ", "
761 << "\"cap\": " << arc->cap << ", "
762 << "\"flow\": " << arc->flow
763 << "}";
764 }
765 out << "\n ]\n";
766 out << "}\n";
767
768 return out.str();
769}
770
771
772//==============================================================================
773// DIMACS FORMAT
774//==============================================================================
775
797template <class Net>
798void export_network_to_dimacs(const Net& net, const std::string& filename)
799{
800 using Node = typename Net::Node;
801
802 std::ofstream out(filename);
803 if (not out)
804 return;
805
806 // Build node ID map (1-based for DIMACS)
808 size_t id = 1; // DIMACS is 1-indexed
809 for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
810 node_ids[it.get_curr()] = id++;
811
812 // Header
813 out << "c Network exported from Aleph-w\n";
814 out << "p max " << net.vsize() << " " << net.esize() << "\n";
815
816 // Source and sink
817 if (net.is_single_source())
818 out << "n " << node_ids[net.get_source()] << " s\n";
819 if (net.is_single_sink())
820 out << "n " << node_ids[net.get_sink()] << " t\n";
821
822 // Arcs
823 for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
824 {
825 auto arc = it.get_curr();
826 out << "a " << node_ids[net.get_src_node(arc)] << " "
827 << node_ids[net.get_tgt_node(arc)] << " "
828 << static_cast<long long>(arc->cap) << "\n";
829 }
830}
831
842template <class Net>
843Net import_network_from_dimacs(const std::string& filename)
844{
845 using Node = typename Net::Node;
846 using Flow_Type = typename Net::Flow_Type;
847
848 Net net;
849 std::ifstream in(filename);
850 if (not in)
851 throw std::runtime_error("Cannot open file: " + filename);
852
853 std::vector<Node*> nodes;
854 size_t source_id = 0, sink_id = 0;
855
856 std::string line;
857 while (std::getline(in, line))
858 {
859 if (line.empty() or line[0] == 'c')
860 continue;
861
862 std::istringstream iss(line);
863 char type;
864 iss >> type;
865
866 if (type == 'p')
867 {
868 std::string problem;
869 size_t n, m;
870 iss >> problem >> n >> m;
871
872 nodes.resize(n + 1); // 1-indexed
873 for (size_t i = 1; i <= n; ++i)
874 nodes[i] = net.insert_node();
875 }
876 else if (type == 'n')
877 {
878 size_t id;
879 char st;
880 iss >> id >> st;
881
882 if (st == 's')
883 source_id = id;
884 else if (st == 't')
885 sink_id = id;
886 }
887 else if (type == 'a')
888 {
889 size_t src, tgt;
890 long long cap;
891 iss >> src >> tgt >> cap;
892
893 net.insert_arc(nodes[src], nodes[tgt],
894 static_cast<Flow_Type>(cap));
895 }
896 }
897
898 // Source and sink nodes are determined by topology in Net_Graph
899 // The DIMACS format's source/sink designations guide network construction
900 (void)source_id; // Suppress unused variable warning
901 (void)sink_id;
902
903 return net;
904}
905
906
907//==============================================================================
908// BENCHMARKING UTILITIES
909//==============================================================================
910
914template <typename Flow_Type>
921
933template <class Net, class Algo>
935benchmark_maxflow(Net& net, Algo algo, const std::string& name)
936{
938 result.algorithm_name = name;
939
940 auto start = std::chrono::high_resolution_clock::now();
941 result.flow_value = algo(net);
942 auto end = std::chrono::high_resolution_clock::now();
943
944 result.elapsed_ms = std::chrono::duration<double, std::milli>(
945 end - start).count();
946
947 return result;
948}
949
953template <typename Flow_Type>
955 const std::vector<MaxFlowBenchmarkResult<Flow_Type>>& results)
956{
957 std::cout << "\n=== Max-Flow Algorithm Benchmark ===\n";
958 std::cout << std::left << std::setw(25) << "Algorithm"
959 << std::setw(15) << "Flow"
960 << std::setw(15) << "Time (ms)" << "\n";
961 std::cout << std::string(55, '-') << "\n";
962
963 for (const auto& r : results)
964 std::cout << std::left << std::setw(25) << r.algorithm_name
965 << std::setw(15) << r.flow_value
966 << std::setw(15) << std::fixed << std::setprecision(3)
967 << r.elapsed_ms << "\n";
968}
969
970} // namespace Aleph
971
972#endif // NET_UTILS_H
WeightedDigraph::Node Node
int num_nodes
Definition btreepic.C:410
void empty() noexcept
empty the list
Definition htlist.H:1689
Generic key-value map implemented on top of a binary search tree.
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
constexpr size_t vsize() const noexcept
Definition graph-dry.H:698
size_t esize() const noexcept
Return the total of arcs of graph.
Definition graph-dry.H:792
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
Definition graph-dry.H:737
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
double Flow_Type
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Net import_network_from_dimacs(const std::string &filename)
Import network from DIMACS max-flow format.
Definition net_utils.H:843
void export_network_to_dimacs(const Net &net, const std::string &filename)
Export network to DIMACS max-flow format.
Definition net_utils.H:798
void export_network_to_dot(const Net &net, const std::string &filename, const DotExportOptions &options=DotExportOptions())
Export network to DOT format for GraphViz visualization.
Definition net_utils.H:462
Net generate_random_network(const NetworkGenParams &params)
Generate a random flow network.
Definition net_utils.H:134
Net generate_bipartite_network(size_t left_size, size_t right_size, double edge_prob=0.5, unsigned seed=0)
Generate a bipartite network for matching.
Definition net_utils.H:301
void export_network_to_json(const Net &net, const std::string &filename)
Export network to JSON format.
Definition net_utils.H:672
std::string network_to_json_string(const Net &net)
Export network to JSON string.
Definition net_utils.H:728
MaxFlowBenchmarkResult< typename Net::Flow_Type > benchmark_maxflow(Net &net, Algo algo, const std::string &name)
Run and time a max-flow algorithm.
Definition net_utils.H:935
Net generate_grid_network(size_t rows, size_t cols, typename Net::Flow_Type capacity, bool bidirectional=true)
Generate a grid network.
Definition net_utils.H:244
void print_benchmark_results(const std::vector< MaxFlowBenchmarkResult< Flow_Type > > &results)
Print benchmark results.
Definition net_utils.H:954
std::string network_to_dot_string(const Net &net, const DotExportOptions &options=DotExportOptions())
Generate DOT string for network (instead of file).
Definition net_utils.H:557
Net generate_layered_network(const std::vector< size_t > &layer_sizes, typename Net::Flow_Type capacity, double edge_prob=0.5, unsigned seed=0)
Generate a layered network.
Definition net_utils.H:363
static long & color(typename GT::Node *p)
DynList< T > maps(const C &c, Op op)
Classic map operation.
static struct argp_option options[]
Definition ntreepic.C:1885
Filtered iterator on all the arcs of a graph.
Definition tpl_graph.H:1164
Options for DOT export.
Definition net_utils.H:427
bool highlight_saturated
Highlight saturated arcs.
Definition net_utils.H:431
std::string source_color
Definition net_utils.H:435
std::string empty_color
Definition net_utils.H:438
bool use_colors
Use colors for flow visualization.
Definition net_utils.H:433
bool show_capacity
Show capacity values on arcs.
Definition net_utils.H:429
bool show_flow
Show flow values on arcs.
Definition net_utils.H:428
bool highlight_empty
Highlight empty arcs.
Definition net_utils.H:432
std::string saturated_color
Definition net_utils.H:437
bool show_cost
Show cost values (for cost networks)
Definition net_utils.H:430
Result of running a max-flow algorithm.
Definition net_utils.H:916
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
constexpr bool is_single_source() const noexcept
Return true if the network has a single source.
Definition tpl_net.H:369
Node * get_source() const
Return an arbitrary source node.
Definition tpl_net.H:548
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
Node * get_sink() const
Return an arbitrary sink node.
Definition tpl_net.H:551
typename Arc::Flow_Type Flow_Type
Capacity/flow numeric type.
Definition tpl_net.H:278
constexpr bool is_single_sink() const noexcept
Return true if the network has a single sink.
Definition tpl_net.H:372
NodeT Node
Node type.
Definition tpl_net.H:275
Parameters for random network generation.
Definition net_utils.H:101
double max_capacity
Maximum arc capacity.
Definition net_utils.H:105
size_t num_arcs
Target number of arcs.
Definition net_utils.H:103
bool ensure_connected
Ensure source can reach sink.
Definition net_utils.H:108
double min_cost
Minimum arc cost (for cost networks)
Definition net_utils.H:106
double min_capacity
Minimum arc capacity.
Definition net_utils.H:104
unsigned seed
Random seed (0 = use time)
Definition net_utils.H:109
double max_cost
Maximum arc cost.
Definition net_utils.H:107
size_t num_nodes
Number of nodes.
Definition net_utils.H:102
Dynamic key-value map based on balanced binary search trees.
Network flow graph structures.
Maximum flow minimum cost network algorithms.
DynList< int > l