Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_net_test.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
33
38#include <gtest/gtest.h>
39
40#include <set>
41
42#include <tpl_net.H>
43
44using namespace Aleph;
45
46namespace
47{
49
50 struct SimpleNet
51 {
52 Net::Node *s = nullptr;
53 Net::Node *a = nullptr;
54 Net::Node *b = nullptr;
55 Net::Node *t = nullptr;
56 Net::Arc *sa = nullptr;
57 Net::Arc *sb = nullptr;
58 Net::Arc *ab = nullptr;
59 Net::Arc *at = nullptr;
60 Net::Arc *bt = nullptr;
61 };
62
64 {
65 SimpleNet sn;
66 sn.s = net.insert_node(0);
67 sn.a = net.insert_node(1);
68 sn.b = net.insert_node(2);
69 sn.t = net.insert_node(3);
70
71 sn.sa = net.insert_arc(sn.s, sn.a, 3, 0);
72 sn.sb = net.insert_arc(sn.s, sn.b, 2, 0);
73 sn.ab = net.insert_arc(sn.a, sn.b, 1, 0);
74 sn.at = net.insert_arc(sn.a, sn.t, 2, 0);
75 sn.bt = net.insert_arc(sn.b, sn.t, 3, 0);
76
77 return sn;
78 }
79
80 struct SingleArcNet
81 {
82 Net::Node *s = nullptr;
83 Net::Node *t = nullptr;
84 Net::Arc *st = nullptr;
85 };
86
87 SingleArcNet build_single_arc(Net &net, int cap, int flow = 0)
88 {
89 SingleArcNet sn;
90 sn.s = net.insert_node(0);
91 sn.t = net.insert_node(1);
92 sn.st = net.insert_arc(sn.s, sn.t, cap, flow);
93 return sn;
94 }
95}
96
98{
99 Net net;
100 auto s = net.insert_node(1);
101 auto t = net.insert_node(2);
102
103 EXPECT_TRUE(net.is_source(s));
104 EXPECT_TRUE(net.is_sink(s));
105 EXPECT_TRUE(net.is_source(t));
106 EXPECT_TRUE(net.is_sink(t));
107
108 auto arc = net.insert_arc(s, t, 5, 0);
109
110 EXPECT_TRUE(net.is_source(s));
111 EXPECT_FALSE(net.is_sink(s));
112 EXPECT_FALSE(net.is_source(t));
113 EXPECT_TRUE(net.is_sink(t));
114
115 net.remove_arc(arc);
116
117 EXPECT_TRUE(net.is_source(s));
118 EXPECT_TRUE(net.is_sink(s));
119 EXPECT_TRUE(net.is_source(t));
120 EXPECT_TRUE(net.is_sink(t));
121}
122
124{
125 Net net;
126 auto s = net.insert_node(1);
127 auto t = net.insert_node(2);
128 auto arc = net.insert_arc(s, t, 5, 0);
129
130 net.disconnect_arc(arc);
131 EXPECT_EQ(net.get_num_arcs(), 0U);
132 EXPECT_TRUE(net.is_source(t));
133 EXPECT_TRUE(net.is_sink(s));
134
135 net.connect_arc(arc);
136 EXPECT_EQ(net.get_num_arcs(), 1U);
137 EXPECT_FALSE(net.is_source(t));
138 EXPECT_FALSE(net.is_sink(s));
139}
140
142{
143 Net net;
144 auto s1 = net.insert_node(1);
145 auto s2 = net.insert_node(2);
146 auto t1 = net.insert_node(3);
147 auto t2 = net.insert_node(4);
148
149 net.insert_arc(s1, t1, 5, 0);
150 net.insert_arc(s2, t2, 7, 0);
151
152 EXPECT_EQ(net.get_src_nodes().size(), 2U);
153 EXPECT_EQ(net.get_sink_nodes().size(), 2U);
154
155 const auto before_nodes = net.get_num_nodes();
156 net.make_super_source();
157
158 EXPECT_EQ(net.get_src_nodes().size(), 1U);
160
161 auto super_source = net.get_source();
162 EXPECT_EQ(net.get_out_degree(super_source), 2U);
163
164 bool has_self = false;
165 for (Node_Arc_Iterator<Net> it(super_source); it.has_curr(); it.next_ne())
166 {
167 if (it.get_tgt_node_ne() == super_source)
168 has_self = true;
169 }
171
174 EXPECT_EQ(net.get_src_nodes().size(), 2U);
175}
176
178{
179 Net net;
180 auto s1 = net.insert_node(1);
181 auto s2 = net.insert_node(2);
182 auto t1 = net.insert_node(3);
183 auto t2 = net.insert_node(4);
184
185 net.insert_arc(s1, t1, 5, 0);
186 net.insert_arc(s2, t2, 7, 0);
187
188 EXPECT_EQ(net.get_sink_nodes().size(), 2U);
189
190 const auto before_nodes = net.get_num_nodes();
191 net.make_super_sink();
192
193 EXPECT_EQ(net.get_sink_nodes().size(), 1U);
195
196 auto super_sink = net.get_sink();
197 EXPECT_EQ(net.get_in_degree(super_sink), 2U);
198
199 bool has_self = false;
200 for (Node_Arc_Iterator<Net> it(super_sink); it.has_curr(); it.next_ne())
201 {
202 if (it.get_tgt_node_ne() == super_sink)
203 has_self = true;
204 }
206
207 net.unmake_super_sink();
209 EXPECT_EQ(net.get_sink_nodes().size(), 2U);
210}
211
213{
214 Net net1;
217 EXPECT_TRUE(net1.check_network());
218 EXPECT_EQ(net1.flow_value(), 5);
219
220 Net net2;
223 EXPECT_TRUE(net2.check_network());
224 EXPECT_EQ(net2.flow_value(), 5);
225}
226
244
246{
247 Net net;
248 auto nodes = build_single_arc(net, 4);
249
250 auto path = find_aumenting_path_dfs(net, 0);
251 auto slack = increase_flow(net, path);
252
253 EXPECT_EQ(slack, 4);
254 EXPECT_EQ(nodes.st->flow, 4);
255}
256
258{
259 Net net;
260 auto nodes = build_single_arc(net, 4);
261
263 DynList<Parc<Net>> semi_path;
264 auto slack = finder.semi_path(nodes.s, nodes.t, semi_path, 0);
265
266 EXPECT_EQ(slack, 4);
267 EXPECT_FALSE(semi_path.is_empty());
268
269 increase_flow(net, semi_path, slack);
270 EXPECT_EQ(nodes.st->flow, 4);
271}
272
294
296{
297 Net net;
298 build_single_arc(net, 10, 4);
299
300 auto residual = preflow_create_residual_net(net);
301 auto &rnet = std::get<0>(residual);
302 using Rnet = PP_Res_Net<Net>;
303
304 Net::Arc *original = nullptr;
305 for (typename Rnet::Arc_Iterator it(rnet); it.has_curr(); it.next_ne())
306 {
307 auto arc = it.get_curr();
308 if (arc->img != nullptr)
309 {
310 original = arc->img;
311 arc->flow = 7;
312 break;
313 }
314 }
315
316 ASSERT_NE(original, nullptr);
318 EXPECT_EQ(original->flow, 7);
319}
320
322{
323 Net net;
324 auto nodes = build_simple_net(net);
325
330
331 auto value = min_cut<Net, Edmonds_Karp_Maximum_Flow>(net, vs, vt, cuts, cutt);
332 EXPECT_EQ(value, 5);
334 EXPECT_TRUE(vt.contains(nodes.t));
335
336 int cut_cap = 0;
337 for (typename DynList<Net::Arc *>::Iterator it(cuts); it.has_curr(); it.next_ne())
338 cut_cap += it.get_curr()->cap;
339
340 EXPECT_EQ(cut_cap, value);
341}
Generic directed graph (digraph) wrapper template.
Definition graph-dry.H:3848
Iterator on the items of list.
Definition htlist.H:1714
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
Dynamic set backed by balanced binary search trees with automatic memory management.
const size_t & size() const
Returns the cardinality of the set.
bool contains(const Key &key) const
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
Augmenting-path search over a directed network.
Definition tpl_net.H:1026
bool has_curr() const noexcept
Return true if iterator has current item.
Definition htlist.H:1150
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
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
#define TEST(name)
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Net::Flow_Type edmonds_karp_maximum_flow(Net &net)
Maximize flow using the Edmonds-Karp algorithm.
Definition tpl_net.H:1551
Net::Flow_Type random_preflow_maximum_flow(Net &net)
Preflow-push maximum flow using a random active-node queue.
Definition tpl_net.H:1830
Path< Net > find_aumenting_path_dfs(const Net &net, const typename Net::Flow_Type &min_slack)
Find an augmenting path using DFS.
Definition tpl_net.H:1253
Net::Flow_Type heap_preflow_maximum_flow(Net &net)
Preflow-push maximum flow using a height-ordered heap.
Definition tpl_net.H:1800
Net::Flow_Type increase_flow(Net &net, const Path< Net > &path)
Increase flow along an augmenting path.
Definition tpl_net.H:918
std::tuple< PP_Res_Net< Net >, typename PP_Res_Net< Net >::Node *, typename PP_Res_Net< Net >::Node * > preflow_create_residual_net(Net &net)
Build the residual network for preflow-push algorithms.
Definition tpl_net.H:1440
Net::Flow_Type fifo_preflow_maximum_flow(Net &net)
Preflow-push maximum flow using a FIFO queue of active nodes.
Definition tpl_net.H:1758
Net::Flow_Type ford_fulkerson_maximum_flow(Net &net)
Maximize flow using the Ford-Fulkerson algorithm.
Definition tpl_net.H:1523
void update_flow(const Rnet &rnet)
Propagate residual arc flows back to their original arcs.
Definition tpl_net.H:1469
DynList< T > maps(const C &c, Op op)
Classic map operation.
Net_Sup_Dem_Graph< SimpleNode, SimpleArc > SimpleNet
Arc of a flow network implemented with adjacency lists.
Definition tpl_net.H:115
Arc filter for residual traversal in flow networks.
Definition tpl_net.H:176
Flow network implemented with adjacency lists.
Definition tpl_net.H:261
void unmake_super_source() noexcept
Restore a super-source network to its original multi-source form.
Definition tpl_net.H:480
Node * insert_node(const Node_Type &node_info)
Insert a new node by copying node_info.
Definition tpl_net.H:559
const DynSetTree< Node * > & get_sink_nodes() const noexcept
Return the set of sink nodes.
Definition tpl_net.H:450
const DynSetTree< Node * > & get_src_nodes() const noexcept
Return the set of source nodes.
Definition tpl_net.H:447
Arc * connect_arc(Arc *arc)
Connect a previously disconnected arc.
Definition tpl_net.H:641
void unmake_super_sink() noexcept
Restore a super-sink network to its original multi-sink form.
Definition tpl_net.H:514
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
bool is_source(Node *node) const noexcept
Return true if node is a source.
Definition tpl_net.H:363
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
void disconnect_arc(Arc *arc) noexcept
Disconnect arc arc from the graph without deleting it.
Definition tpl_net.H:691
ArcT Arc
Arc type.
Definition tpl_net.H:272
Node * get_sink() const
Return an arbitrary sink node.
Definition tpl_net.H:551
bool is_sink(Node *node) const noexcept
Return true if node is a sink.
Definition tpl_net.H:366
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
Filtered iterator of adjacent arcs of a node.
Definition tpl_graph.H:1119
Network flow graph structures.