1 | /** \file |
2 | * \brief Tests for Min-Cost Flow Algorithms |
3 | * |
4 | * \author Stephan Beyer |
5 | * |
6 | * \par License: |
7 | * This file is part of the Open Graph Drawing Framework (OGDF). |
8 | * |
9 | * \par |
10 | * Copyright (C)<br> |
11 | * See README.md in the OGDF root directory for details. |
12 | * |
13 | * \par |
14 | * This program is free software; you can redistribute it and/or |
15 | * modify it under the terms of the GNU General Public License |
16 | * Version 2 or 3 as published by the Free Software Foundation; |
17 | * see the file LICENSE.txt included in the packaging of this file |
18 | * for details. |
19 | * |
20 | * \par |
21 | * This program is distributed in the hope that it will be useful, |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
24 | * GNU General Public License for more details. |
25 | * |
26 | * \par |
27 | * You should have received a copy of the GNU General Public |
28 | * License along with this program; if not, see |
29 | * http://www.gnu.org/copyleft/gpl.html |
30 | */ |
31 | |
32 | #include "ogdf/graphalg/MinCostFlowReinelt.h" |
33 | #include <testing.h> |
34 | |
35 | template<typename TCost> |
36 | void testModule(const char *name, MinCostFlowModule<TCost> *alg, TCost base) |
37 | { |
38 | describe(name, [&]() { |
39 | Graph G; |
40 | node s = G.newNode(); |
41 | node a = G.newNode(); |
42 | node b = G.newNode(); |
43 | node t = G.newNode(); |
44 | edge sa = G.newEdge(s, a); |
45 | edge sb = G.newEdge(s, b); |
46 | edge at = G.newEdge(a, t); |
47 | edge bt = G.newEdge(b, t); |
48 | edge ab = G.newEdge(a, b); |
49 | EdgeArray<int> lb(G, 0); |
50 | it("works with costs all being zero" , [&]() { |
51 | EdgeArray<int> cap(G, 10000); |
52 | cap[ab] = 1; |
53 | EdgeArray<TCost> cost(G, 0); |
54 | NodeArray<int> supply(G, 0); |
55 | supply[s] = 20000; |
56 | supply[t] = -20000; |
57 | EdgeArray<int> flow(G); |
58 | bool feasible = alg->call(G, lb, cap, cost, supply, flow); |
59 | |
60 | AssertThat(feasible, Equals(true)); |
61 | AssertThat(flow[sa], Equals(10000)); |
62 | AssertThat(flow[sb], Equals(10000)); |
63 | AssertThat(flow[at], Equals(10000)); |
64 | AssertThat(flow[bt], Equals(10000)); |
65 | AssertThat(flow[ab], Equals(0)); |
66 | }); |
67 | it("works with non-negative cost" , [&]() { |
68 | EdgeArray<int> cap(G, 10000); |
69 | cap[ab] = 1; |
70 | EdgeArray<TCost> cost(G, 100*base); |
71 | cost[at] = 99*base; |
72 | cost[ab] = 0; |
73 | cost[sa] = base; |
74 | cost[bt] = base; |
75 | NodeArray<int> supply(G, 0); |
76 | supply[s] = 10000; |
77 | supply[t] = -10000; |
78 | EdgeArray<int> flow(G); |
79 | bool feasible = alg->call(G, lb, cap, cost, supply, flow); |
80 | |
81 | AssertThat(feasible, Equals(true)); |
82 | AssertThat(flow[sa], Equals(10000)); |
83 | AssertThat(flow[sb], Equals(0)); |
84 | AssertThat(flow[at], Equals(9999)); |
85 | AssertThat(flow[bt], Equals(1)); |
86 | AssertThat(flow[ab], Equals(1)); |
87 | }); |
88 | it("works with positive and negative cost" , [&]() { |
89 | EdgeArray<int> cap(G, 10000); |
90 | cap[ab] = 1; |
91 | EdgeArray<TCost> cost(G, base); |
92 | cost[ab] = -base; |
93 | NodeArray<int> supply(G, 0); |
94 | supply[s] = 10000; |
95 | supply[t] = -10000; |
96 | EdgeArray<int> flow(G); |
97 | bool feasible = alg->call(G, lb, cap, cost, supply, flow); |
98 | |
99 | AssertThat(feasible, Equals(true)); |
100 | AssertThat(flow[sa], Equals(10000)); |
101 | AssertThat(flow[sb], Equals(0)); |
102 | AssertThat(flow[at], Equals(9999)); |
103 | AssertThat(flow[bt], Equals(1)); |
104 | AssertThat(flow[ab], Equals(1)); |
105 | }); |
106 | it("is unfeasible if supply = demand > edge capacities" , [&]() { |
107 | EdgeArray<int> cap(G, 10000); |
108 | cap[sb] = cap[at] = 5000; |
109 | cap[ab] = 1; |
110 | EdgeArray<TCost> cost(G, -base); |
111 | NodeArray<int> supply(G, 0); |
112 | supply[s] = 15000; |
113 | supply[t] = -15000; |
114 | EdgeArray<int> flow(G); |
115 | bool feasible = alg->call(G, lb, cap, cost, supply, flow); |
116 | |
117 | AssertThat(feasible, Equals(false)); |
118 | }); |
119 | }); |
120 | delete alg; |
121 | } |
122 | |
123 | go_bandit([]() { |
124 | describe("Min-Cost Flow algorithms" , []() { |
125 | testModule<int>("MinCostFlowReinelt with integral cost" , new MinCostFlowReinelt<int>(), 1); |
126 | testModule<double>("MinCostFlowReinelt wit real (double) cost [1]" , new MinCostFlowReinelt<double>(), 1.92); |
127 | testModule<double>("MinCostFlowReinelt wit real (double) cost [2]" , new MinCostFlowReinelt<double>(), 0.1432); |
128 | }); |
129 | }); |
130 | |