Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
net_utils_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
102#include <iostream>
103#include <string>
104#include <vector>
105#include <iomanip>
106#include <fstream>
107#include <sstream>
108#include <chrono>
109#include <limits>
110#include <tpl_net.H>
111#include <tpl_maxflow.H>
112#include <net_utils.H>
113
114using namespace std;
115using namespace Aleph;
116
117// Type definitions
121
122static size_t density_to_num_arcs(size_t n, double density)
123{
124 if (n < 2)
125 return 0;
126
127 const double max_arcs = static_cast<double>(n) * (n - 1);
128 size_t m = static_cast<size_t>(density * max_arcs);
129 if (m < n - 1)
130 m = n - 1;
131 return m;
132}
133
135{
136 vector<Node*> nodes;
137 for (auto it = net.get_node_it(); it.has_curr(); it.next())
138 nodes.push_back(it.get_curr());
139
141 for (auto it = net.get_arc_it(); it.has_curr(); it.next())
142 total_cap += it.get_curr()->cap;
143 if (total_cap <= FlowType{0})
144 total_cap = FlowType{1};
145
146 const FlowType cap = total_cap;
147 auto s = net.insert_node("SuperSource");
148 auto t = net.insert_node("SuperSink");
149
150 for (Node* v : nodes)
151 {
152 net.insert_arc(s, v, cap);
153 net.insert_arc(v, t, cap);
154 }
155}
156
160void print_network_stats(Net& net, const string& title)
161{
162 cout << "\n=== " << title << " ===" << endl;
163 cout << "Nodes: " << net.get_num_nodes() << endl;
164 cout << "Arcs: " << net.get_num_arcs() << endl;
165
166 // Calculate density
167 size_t n = net.get_num_nodes();
168 size_t m = net.get_num_arcs();
169 double max_arcs = n * (n - 1); // Directed graph
170 double density = (max_arcs > 0) ? 100.0 * m / max_arcs : 0;
171
172 cout << "Density: " << fixed << setprecision(1) << density << "%" << endl;
173
174 // Calculate total capacity
176 for (auto it = net.get_arc_it(); it.has_curr(); it.next())
177 total_cap += it.get_curr()->cap;
178
179 cout << "Total capacity: " << total_cap << endl;
180}
181
186{
187 cout << "\n" << string(60, '=') << endl;
188 cout << "Demo 1: Random Network Generation" << endl;
189 cout << string(60, '=') << endl;
190
191 cout << "\nGenerating random networks with different parameters..." << endl;
192
193 // Small sparse network
194 {
195 Net net = generate_random_network<Net>(10, density_to_num_arcs(10, 0.2), 1.0, 10.0);
196 print_network_stats(net, "Small Sparse (n=10, density=20%)");
197
199 FlowType flow = dinic_maximum_flow(net);
200 cout << "Max flow: " << flow << endl;
201 }
202
203 // Medium network
204 {
205 Net net = generate_random_network<Net>(20, density_to_num_arcs(20, 0.3), 5.0, 50.0);
206 print_network_stats(net, "Medium (n=20, density=30%)");
207
209 FlowType flow = dinic_maximum_flow(net);
210 cout << "Max flow: " << flow << endl;
211 }
212
213 // Dense network
214 {
215 Net net = generate_random_network<Net>(15, density_to_num_arcs(15, 0.6), 1.0, 100.0);
216 print_network_stats(net, "Dense (n=15, density=60%)");
217
219 FlowType flow = dinic_maximum_flow(net);
220 cout << "Max flow: " << flow << endl;
221 }
222}
223
228{
229 cout << "\n" << string(60, '=') << endl;
230 cout << "Demo 2: Grid Network Generation" << endl;
231 cout << string(60, '=') << endl;
232
233 cout << "\nGrid networks are useful for benchmarking." << endl;
234 cout << "Source is top-left, sink is bottom-right.\n" << endl;
235
236 // Different grid sizes
237 for (int size : {3, 5, 8})
238 {
239 Net net = generate_grid_network<Net>(size, size, 10.0, false);
240
241 stringstream title;
242 title << size << "x" << size << " Grid";
243 print_network_stats(net, title.str());
244
245 auto start = chrono::high_resolution_clock::now();
246 FlowType flow = dinic_maximum_flow(net);
247 auto end = chrono::high_resolution_clock::now();
248
249 double ms = chrono::duration<double, milli>(end - start).count();
250 cout << "Max flow: " << flow << " (computed in "
251 << fixed << setprecision(3) << ms << " ms)" << endl;
252 }
253}
254
259{
260 cout << "\n" << string(60, '=') << endl;
261 cout << "Demo 3: Layered Network Generation" << endl;
262 cout << string(60, '=') << endl;
263
264 cout << "\nLayered networks have nodes in discrete layers." << endl;
265 cout << "Edges only go from one layer to the next (DAG structure).\n" << endl;
266
267 vector<size_t> layers = {1, 3, 4, 3, 1}; // Source, 3, 4, 3, Sink
268
269 Net net = generate_layered_network<Net>(layers, 20.0, 0.7);
270
271 cout << "Layer structure: ";
272 for (size_t l : layers)
273 cout << l << " ";
274 cout << endl;
275
276 print_network_stats(net, "Layered Network");
277
278 FlowType flow = dinic_maximum_flow(net);
279 cout << "Max flow: " << flow << endl;
280
281 cout << "\nLayered networks model:" << endl;
282 cout << " - Assembly lines (stages of production)" << endl;
283 cout << " - Communication protocols (network layers)" << endl;
284 cout << " - Project scheduling (phases)" << endl;
285}
286
291{
292 cout << "\n" << string(60, '=') << endl;
293 cout << "Demo 4: GraphViz DOT Export" << endl;
294 cout << string(60, '=') << endl;
295
296 cout << "\nCreating a small network and exporting to DOT format..." << endl;
297
298 // Create a simple network
299 Net net;
300
301 auto s = net.insert_node("Source");
302 auto a = net.insert_node("A");
303 auto b = net.insert_node("B");
304 auto c = net.insert_node("C");
305 auto t = net.insert_node("Sink");
306
307 net.insert_arc(s, a, 10);
308 net.insert_arc(s, b, 8);
309 net.insert_arc(a, b, 5);
310 net.insert_arc(a, c, 7);
311 net.insert_arc(b, c, 6);
312 net.insert_arc(b, t, 9);
313 net.insert_arc(c, t, 12);
314
315 // Compute max flow first
316 FlowType flow = dinic_maximum_flow(net);
317 cout << "Max flow computed: " << flow << endl;
318
319 // Export to DOT string
321 opts.graph_name = "sample_network";
322 opts.show_capacity = true;
323 opts.show_flow = true;
324
325 string dot = network_to_dot_string(net, opts);
326
327 cout << "\nDOT output:" << endl;
328 cout << string(40, '-') << endl;
329 cout << dot;
330 cout << string(40, '-') << endl;
331
332 cout << "\nTo visualize, save to .dot file and run:" << endl;
333 cout << " dot -Tpng network.dot -o network.png" << endl;
334
335 cout << "\nCommands to visualize DOT files:" << endl;
336 cout << " dot -Tpng network.dot -o network.png" << endl;
337 cout << " dot -Tsvg network.dot -o network.svg" << endl;
338}
339
344{
345 cout << "\n" << string(60, '=') << endl;
346 cout << "Demo 5: JSON Serialization" << endl;
347 cout << string(60, '=') << endl;
348
349 cout << "\nExporting network to JSON format..." << endl;
350
351 // Create a small network
352 Net net = generate_random_network<Net>(5, density_to_num_arcs(5, 0.4), 1.0, 10.0);
355
356 string json = network_to_json_string(net);
357
358 cout << "\nJSON output:" << endl;
359 cout << string(40, '-') << endl;
360 cout << json << endl;
361 cout << string(40, '-') << endl;
362
363 cout << "\nJSON format is useful for:" << endl;
364 cout << " - Web visualization (D3.js, vis.js)" << endl;
365 cout << " - Data exchange between systems" << endl;
366 cout << " - Storing network configurations" << endl;
367}
368
373{
374 cout << "\n" << string(60, '=') << endl;
375 cout << "Demo 6: Algorithm Benchmarking" << endl;
376 cout << string(60, '=') << endl;
377
378 cout << "\nComparing max-flow algorithms on different network types...\n" << endl;
379
380 cout << setw(20) << left << "Network Type"
381 << setw(10) << "Nodes"
382 << setw(10) << "Arcs"
383 << setw(16) << "F-F (DFS) (ms)"
384 << setw(12) << "Dinic (ms)"
385 << setw(10) << "Flow" << endl;
386 cout << string(74, '-') << endl;
387
388 auto benchmark = [](Net& net, const string& name) {
389 size_t n = net.get_num_nodes();
390 size_t m = net.get_num_arcs();
391
392 // Ford-Fulkerson (DFS augmenting paths)
393 Net net1 = net; // Copy
395 auto t1 = chrono::high_resolution_clock::now();
397 auto t2 = chrono::high_resolution_clock::now();
398 double ek_ms = chrono::duration<double, milli>(t2 - t1).count();
399
400 // Dinic
401 Net net2 = net;
403 t1 = chrono::high_resolution_clock::now();
405 t2 = chrono::high_resolution_clock::now();
406 double dinic_ms = chrono::duration<double, milli>(t2 - t1).count();
407
408 cout << setw(20) << left << name
409 << setw(10) << n
410 << setw(10) << m
411 << setw(16) << fixed << setprecision(3) << ek_ms
412 << setw(12) << dinic_ms
413 << setw(10) << setprecision(0) << f1 << endl;
414 };
415
416 // Random sparse
417 {
418 Net net = generate_random_network<Net>(30, density_to_num_arcs(30, 0.15), 1.0, 100.0);
419 benchmark(net, "Random Sparse");
420 }
421
422 // Random dense
423 {
424 Net net = generate_random_network<Net>(20, density_to_num_arcs(20, 0.5), 1.0, 100.0);
425 benchmark(net, "Random Dense");
426 }
427
428 // Grid
429 {
430 Net net = generate_grid_network<Net>(8, 8, 50.0, false);
431 benchmark(net, "Grid 8x8");
432 }
433
434 // Layered
435 {
436 vector<size_t> layers = {1, 5, 8, 8, 5, 1};
437 Net net = generate_layered_network<Net>(layers, 50.0, 0.6);
438 benchmark(net, "Layered (6 layers)");
439 }
440
441 cout << "\nNote: Times may vary based on random network structure." << endl;
442 cout << "Dinic is generally faster, especially on dense networks." << endl;
443}
444
445int main()
446{
447 cout << "=== Network Utilities ===" << endl;
448 cout << "Generation, Visualization, and Serialization\n" << endl;
449
456
457 // Summary
458 cout << "\n" << string(60, '=') << endl;
459 cout << "Summary" << endl;
460 cout << string(60, '=') << endl;
461
462 cout << R"(
463Network Utilities in Aleph-w:
464
465Generation Functions:
466 - generate_random_network(n, m, min_cap, max_cap)
467 - generate_grid_network(rows, cols, capacity, bidirectional)
468 - generate_layered_network(layers, capacity, edge_prob)
469 - generate_bipartite_network(left, right, edge_prob)
470
471Visualization (DOT/GraphViz):
472 - export_network_to_dot(net, filename, options)
473 - network_to_dot_string(net, options)
474
475 Visualize with: dot -Tpng network.dot -o network.png
476
477Serialization:
478 - network_to_json_string(net)
479 - export_network_to_dimacs(net, filename)
480 - import_network_from_dimacs<Net>(filename)
481
482Use Cases:
483 - Algorithm testing and benchmarking
484 - Educational demonstrations
485 - Network visualization
486 - Data exchange between systems
487)" << endl;
488
489 return 0;
490}
WeightedDigraph::Node Node
auto get_arc_it() const noexcept
Obtains an iterator to the arc of graph.
Definition graph-dry.H:2802
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Definition graph-dry.H:695
constexpr size_t get_num_arcs() const noexcept
Definition graph-dry.H:778
auto get_node_it() const noexcept
Obtains an iterator to the nodes of graph.
Definition graph-dry.H:2780
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
double FlowType
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
size_t size(Node *root) noexcept
Net::Flow_Type dinic_maximum_flow(Net &net)
Compute maximum flow using Dinic's algorithm.
std::string network_to_json_string(const Net &net)
Export network to JSON string.
Definition net_utils.H:728
Net::Flow_Type ford_fulkerson_maximum_flow(Net &net)
Maximize flow using the Ford-Fulkerson algorithm.
Definition tpl_net.H:1523
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
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
Network flow utilities: generators, visualization, serialization.
void demo_benchmarking()
Demo 6: Benchmarking.
void demo_json_export()
Demo 5: JSON Serialization.
void demo_random_networks()
Demo 1: Random Network Generation.
static void add_super_source_and_sink(Net &net)
static size_t density_to_num_arcs(size_t n, double density)
void demo_dot_export()
Demo 4: DOT Export for Visualization.
void demo_layered_networks()
Demo 3: Layered Network Generation.
void print_network_stats(Net &net, const string &title)
Print network statistics.
int main()
void demo_grid_networks()
Demo 2: Grid Network Generation.
Options for DOT export.
Definition net_utils.H:427
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
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
NodeT Node
Node type.
Definition tpl_net.H:275
Advanced maximum flow algorithms.
Network flow graph structures.
DynList< int > l