2
4
0
1 | 1 |
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) |
2 | 2 |
|
3 | 3 |
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon) |
4 | 4 |
|
5 | 5 |
SET(TESTS |
6 | 6 |
bfs_test |
7 |
circulation_test |
|
7 | 8 |
counter_test |
8 | 9 |
dfs_test |
9 | 10 |
digraph_test |
10 | 11 |
dijkstra_test |
11 | 12 |
dim_test |
12 | 13 |
error_test |
14 |
graph_adaptor_test |
|
13 | 15 |
graph_copy_test |
14 | 16 |
graph_test |
15 | 17 |
graph_utils_test |
16 | 18 |
hao_orlin_test |
17 | 19 |
heap_test |
18 | 20 |
kruskal_test |
19 | 21 |
maps_test |
20 | 22 |
max_matching_test |
23 |
path_test |
|
24 |
preflow_test |
|
21 | 25 |
random_test |
22 |
|
|
26 |
suurballe_test |
|
23 | 27 |
time_measure_test |
24 | 28 |
unionfind_test) |
25 | 29 |
|
26 | 30 |
FOREACH(TEST_NAME ${TESTS}) |
27 | 31 |
ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc) |
28 | 32 |
TARGET_LINK_LIBRARIES(${TEST_NAME} lemon) |
29 | 33 |
ADD_TEST(${TEST_NAME} ${TEST_NAME}) |
30 | 34 |
ENDFOREACH(TEST_NAME) |
1 | 1 |
EXTRA_DIST += \ |
2 |
test/CMakeLists.txt \ |
|
3 |
test/min_cost_flow_test.lgf \ |
|
4 |
|
|
2 |
test/CMakeLists.txt |
|
5 | 3 |
|
6 | 4 |
noinst_HEADERS += \ |
7 | 5 |
test/graph_test.h \ |
8 | 6 |
test/test_tools.h |
9 | 7 |
|
10 | 8 |
check_PROGRAMS += \ |
11 | 9 |
test/bfs_test \ |
12 | 10 |
test/circulation_test \ |
13 | 11 |
test/counter_test \ |
14 | 12 |
test/dfs_test \ |
15 | 13 |
test/digraph_test \ |
16 | 14 |
test/dijkstra_test \ |
17 | 15 |
test/dim_test \ |
18 | 16 |
test/error_test \ |
19 | 17 |
test/graph_adaptor_test \ |
20 | 18 |
test/graph_copy_test \ |
21 | 19 |
test/graph_test \ |
22 | 20 |
test/graph_utils_test \ |
21 |
test/hao_orlin_test \ |
|
23 | 22 |
test/heap_test \ |
24 | 23 |
test/kruskal_test \ |
25 |
test/hao_orlin_test \ |
|
26 | 24 |
test/maps_test \ |
27 | 25 |
test/max_matching_test \ |
28 |
test/random_test \ |
|
29 | 26 |
test/path_test \ |
30 | 27 |
test/preflow_test \ |
28 |
test/random_test \ |
|
31 | 29 |
test/suurballe_test \ |
32 | 30 |
test/test_tools_fail \ |
33 | 31 |
test/test_tools_pass \ |
34 | 32 |
test/time_measure_test \ |
35 | 33 |
test/unionfind_test |
36 | 34 |
|
37 | 35 |
TESTS += $(check_PROGRAMS) |
38 | 36 |
XFAIL_TESTS += test/test_tools_fail$(EXEEXT) |
39 | 37 |
|
40 | 38 |
test_bfs_test_SOURCES = test/bfs_test.cc |
41 | 39 |
test_circulation_test_SOURCES = test/circulation_test.cc |
42 | 40 |
test_counter_test_SOURCES = test/counter_test.cc |
43 | 41 |
test_dfs_test_SOURCES = test/dfs_test.cc |
44 | 42 |
test_digraph_test_SOURCES = test/digraph_test.cc |
45 | 43 |
test_dijkstra_test_SOURCES = test/dijkstra_test.cc |
46 | 44 |
test_dim_test_SOURCES = test/dim_test.cc |
47 | 45 |
test_error_test_SOURCES = test/error_test.cc |
48 | 46 |
test_graph_adaptor_test_SOURCES = test/graph_adaptor_test.cc |
49 | 47 |
test_graph_copy_test_SOURCES = test/graph_copy_test.cc |
50 | 48 |
test_graph_test_SOURCES = test/graph_test.cc |
51 | 49 |
test_graph_utils_test_SOURCES = test/graph_utils_test.cc |
52 | 50 |
test_heap_test_SOURCES = test/heap_test.cc |
53 | 51 |
test_kruskal_test_SOURCES = test/kruskal_test.cc |
54 | 52 |
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc |
55 | 53 |
test_maps_test_SOURCES = test/maps_test.cc |
56 | 54 |
test_max_matching_test_SOURCES = test/max_matching_test.cc |
57 | 55 |
test_path_test_SOURCES = test/path_test.cc |
58 | 56 |
test_preflow_test_SOURCES = test/preflow_test.cc |
59 | 57 |
test_suurballe_test_SOURCES = test/suurballe_test.cc |
60 | 58 |
test_random_test_SOURCES = test/random_test.cc |
61 | 59 |
test_test_tools_fail_SOURCES = test/test_tools_fail.cc |
62 | 60 |
test_test_tools_pass_SOURCES = test/test_tools_pass.cc |
63 | 61 |
test_time_measure_test_SOURCES = test/time_measure_test.cc |
64 | 62 |
test_unionfind_test_SOURCES = test/unionfind_test.cc |
1 | 1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
2 | 2 |
* |
3 | 3 |
* This file is a part of LEMON, a generic C++ optimization library. |
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
10 | 10 |
* provided that this copyright notice appears in all copies. For |
11 | 11 |
* precise terms see the accompanying LICENSE file. |
12 | 12 |
* |
13 | 13 |
* This software is provided "AS IS" with no warranty of any kind, |
14 | 14 |
* express or implied, and with no claim as to its suitability for any |
15 | 15 |
* purpose. |
16 | 16 |
* |
17 | 17 |
*/ |
18 | 18 |
|
19 |
#include <fstream> |
|
20 |
#include <string> |
|
19 |
#include <iostream> |
|
21 | 20 |
|
22 | 21 |
#include "test_tools.h" |
23 | 22 |
#include <lemon/smart_graph.h> |
24 | 23 |
#include <lemon/preflow.h> |
25 | 24 |
#include <lemon/concepts/digraph.h> |
26 | 25 |
#include <lemon/concepts/maps.h> |
27 | 26 |
#include <lemon/lgf_reader.h> |
28 | 27 |
#include <lemon/elevator.h> |
29 | 28 |
|
30 | 29 |
using namespace lemon; |
31 | 30 |
|
31 |
char test_lgf[] = |
|
32 |
"@nodes\n" |
|
33 |
"label\n" |
|
34 |
"0\n" |
|
35 |
"1\n" |
|
36 |
"2\n" |
|
37 |
"3\n" |
|
38 |
"4\n" |
|
39 |
"5\n" |
|
40 |
"6\n" |
|
41 |
"7\n" |
|
42 |
"8\n" |
|
43 |
"9\n" |
|
44 |
"@arcs\n" |
|
45 |
" label capacity\n" |
|
46 |
"0 1 0 20\n" |
|
47 |
"0 2 1 0\n" |
|
48 |
"1 1 2 3\n" |
|
49 |
"1 2 3 8\n" |
|
50 |
"1 3 4 8\n" |
|
51 |
"2 5 5 5\n" |
|
52 |
"3 2 6 5\n" |
|
53 |
"3 5 7 5\n" |
|
54 |
"3 6 8 5\n" |
|
55 |
"4 3 9 3\n" |
|
56 |
"5 7 10 3\n" |
|
57 |
"5 6 11 10\n" |
|
58 |
"5 8 12 10\n" |
|
59 |
"6 8 13 8\n" |
|
60 |
"8 9 14 20\n" |
|
61 |
"8 1 15 5\n" |
|
62 |
"9 5 16 5\n" |
|
63 |
"@attributes\n" |
|
64 |
"source 1\n" |
|
65 |
"target 8\n"; |
|
66 |
|
|
32 | 67 |
void checkPreflowCompile() |
33 | 68 |
{ |
34 | 69 |
typedef int VType; |
35 | 70 |
typedef concepts::Digraph Digraph; |
36 | 71 |
|
37 | 72 |
typedef Digraph::Node Node; |
38 | 73 |
typedef Digraph::Arc Arc; |
39 | 74 |
typedef concepts::ReadMap<Arc,VType> CapMap; |
40 | 75 |
typedef concepts::ReadWriteMap<Arc,VType> FlowMap; |
41 | 76 |
typedef concepts::WriteMap<Node,bool> CutMap; |
42 | 77 |
|
43 | 78 |
typedef Elevator<Digraph, Digraph::Node> Elev; |
44 | 79 |
typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev; |
45 | 80 |
|
46 | 81 |
Digraph g; |
47 | 82 |
Node n; |
48 | 83 |
Arc e; |
49 | 84 |
CapMap cap; |
50 | 85 |
FlowMap flow; |
51 | 86 |
CutMap cut; |
52 | 87 |
|
53 | 88 |
Preflow<Digraph, CapMap> |
54 | 89 |
::SetFlowMap<FlowMap> |
55 | 90 |
::SetElevator<Elev> |
56 | 91 |
::SetStandardElevator<LinkedElev> |
57 | 92 |
::Create preflow_test(g,cap,n,n); |
58 | 93 |
|
59 | 94 |
preflow_test.capacityMap(cap); |
60 | 95 |
flow = preflow_test.flowMap(); |
61 | 96 |
preflow_test.flowMap(flow); |
62 | 97 |
preflow_test.source(n); |
63 | 98 |
preflow_test.target(n); |
64 | 99 |
|
65 | 100 |
preflow_test.init(); |
66 | 101 |
preflow_test.init(cap); |
67 | 102 |
preflow_test.startFirstPhase(); |
68 | 103 |
preflow_test.startSecondPhase(); |
69 | 104 |
preflow_test.run(); |
70 | 105 |
preflow_test.runMinCut(); |
71 | 106 |
|
72 | 107 |
preflow_test.flowValue(); |
73 | 108 |
preflow_test.minCut(n); |
74 | 109 |
preflow_test.minCutMap(cut); |
75 | 110 |
preflow_test.flow(e); |
76 | 111 |
|
77 | 112 |
} |
78 | 113 |
|
79 | 114 |
int cutValue (const SmartDigraph& g, |
80 | 115 |
const SmartDigraph::NodeMap<bool>& cut, |
81 | 116 |
const SmartDigraph::ArcMap<int>& cap) { |
82 | 117 |
|
83 | 118 |
int c=0; |
84 | 119 |
for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) { |
85 | 120 |
if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e]; |
86 | 121 |
} |
87 | 122 |
return c; |
88 | 123 |
} |
89 | 124 |
|
90 | 125 |
bool checkFlow(const SmartDigraph& g, |
91 | 126 |
const SmartDigraph::ArcMap<int>& flow, |
92 | 127 |
const SmartDigraph::ArcMap<int>& cap, |
93 | 128 |
SmartDigraph::Node s, SmartDigraph::Node t) { |
94 | 129 |
|
95 | 130 |
for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) { |
96 | 131 |
if (flow[e] < 0 || flow[e] > cap[e]) return false; |
97 | 132 |
} |
98 | 133 |
|
99 | 134 |
for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) { |
100 | 135 |
if (n == s || n == t) continue; |
101 | 136 |
int sum = 0; |
102 | 137 |
for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) { |
103 | 138 |
sum += flow[e]; |
104 | 139 |
} |
105 | 140 |
for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) { |
106 | 141 |
sum -= flow[e]; |
107 | 142 |
} |
108 | 143 |
if (sum != 0) return false; |
109 | 144 |
} |
110 | 145 |
return true; |
111 | 146 |
} |
112 | 147 |
|
113 | 148 |
int main() { |
114 | 149 |
|
115 | 150 |
typedef SmartDigraph Digraph; |
116 | 151 |
|
117 | 152 |
typedef Digraph::Node Node; |
118 | 153 |
typedef Digraph::NodeIt NodeIt; |
119 | 154 |
typedef Digraph::ArcIt ArcIt; |
120 | 155 |
typedef Digraph::ArcMap<int> CapMap; |
121 | 156 |
typedef Digraph::ArcMap<int> FlowMap; |
122 | 157 |
typedef Digraph::NodeMap<bool> CutMap; |
123 | 158 |
|
124 | 159 |
typedef Preflow<Digraph, CapMap> PType; |
125 | 160 |
|
126 |
std::string f_name; |
|
127 |
if( getenv("srcdir") ) |
|
128 |
f_name = std::string(getenv("srcdir")); |
|
129 |
else f_name = "."; |
|
130 |
f_name += "/test/preflow_graph.lgf"; |
|
131 |
|
|
132 |
std::ifstream file(f_name.c_str()); |
|
133 |
|
|
134 |
check(file, "Input file '" << f_name << "' not found."); |
|
135 |
|
|
136 | 161 |
Digraph g; |
137 | 162 |
Node s, t; |
138 | 163 |
CapMap cap(g); |
139 |
|
|
164 |
std::istringstream input(test_lgf); |
|
165 |
DigraphReader<Digraph>(g,input). |
|
140 | 166 |
arcMap("capacity", cap). |
141 | 167 |
node("source",s). |
142 | 168 |
node("target",t). |
143 | 169 |
run(); |
144 | 170 |
|
145 | 171 |
PType preflow_test(g, cap, s, t); |
146 | 172 |
preflow_test.run(); |
147 | 173 |
|
148 | 174 |
check(checkFlow(g, preflow_test.flowMap(), cap, s, t), |
149 | 175 |
"The flow is not feasible."); |
150 | 176 |
|
151 | 177 |
CutMap min_cut(g); |
152 | 178 |
preflow_test.minCutMap(min_cut); |
153 | 179 |
int min_cut_value=cutValue(g,min_cut,cap); |
154 | 180 |
|
155 | 181 |
check(preflow_test.flowValue() == min_cut_value, |
156 | 182 |
"The max flow value is not equal to the three min cut values."); |
157 | 183 |
|
158 | 184 |
FlowMap flow(g); |
159 | 185 |
for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e]; |
160 | 186 |
|
161 | 187 |
int flow_value=preflow_test.flowValue(); |
162 | 188 |
|
163 | 189 |
for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e]; |
164 | 190 |
preflow_test.init(flow); |
165 | 191 |
preflow_test.startFirstPhase(); |
166 | 192 |
|
167 | 193 |
CutMap min_cut1(g); |
168 | 194 |
preflow_test.minCutMap(min_cut1); |
169 | 195 |
min_cut_value=cutValue(g,min_cut1,cap); |
170 | 196 |
|
171 | 197 |
check(preflow_test.flowValue() == min_cut_value && |
172 | 198 |
min_cut_value == 2*flow_value, |
173 | 199 |
"The max flow value or the min cut value is wrong."); |
174 | 200 |
|
175 | 201 |
preflow_test.startSecondPhase(); |
176 | 202 |
|
177 | 203 |
check(checkFlow(g, preflow_test.flowMap(), cap, s, t), |
178 | 204 |
"The flow is not feasible."); |
179 | 205 |
|
180 | 206 |
CutMap min_cut2(g); |
181 | 207 |
preflow_test.minCutMap(min_cut2); |
182 | 208 |
min_cut_value=cutValue(g,min_cut2,cap); |
183 | 209 |
|
184 | 210 |
check(preflow_test.flowValue() == min_cut_value && |
185 | 211 |
min_cut_value == 2*flow_value, |
186 | 212 |
"The max flow value or the three min cut values were not doubled"); |
187 | 213 |
1 | 1 |
/* -*- C++ -*- |
2 | 2 |
* |
3 | 3 |
* This file is a part of LEMON, a generic C++ optimization library |
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
10 | 10 |
* provided that this copyright notice appears in all copies. For |
11 | 11 |
* precise terms see the accompanying LICENSE file. |
12 | 12 |
* |
13 | 13 |
* This software is provided "AS IS" with no warranty of any kind, |
14 | 14 |
* express or implied, and with no claim as to its suitability for any |
15 | 15 |
* purpose. |
16 | 16 |
* |
17 | 17 |
*/ |
18 | 18 |
|
19 | 19 |
#include <iostream> |
20 |
#include <fstream> |
|
21 | 20 |
|
22 | 21 |
#include <lemon/list_graph.h> |
23 | 22 |
#include <lemon/lgf_reader.h> |
24 | 23 |
#include <lemon/path.h> |
25 | 24 |
#include <lemon/suurballe.h> |
26 | 25 |
|
27 | 26 |
#include "test_tools.h" |
28 | 27 |
|
29 | 28 |
using namespace lemon; |
30 | 29 |
|
30 |
char test_lgf[] = |
|
31 |
"@nodes\n" |
|
32 |
"label supply1 supply2 supply3\n" |
|
33 |
"1 0 20 27\n" |
|
34 |
"2 0 -4 0\n" |
|
35 |
"3 0 0 0\n" |
|
36 |
"4 0 0 0\n" |
|
37 |
"5 0 9 0\n" |
|
38 |
"6 0 -6 0\n" |
|
39 |
"7 0 0 0\n" |
|
40 |
"8 0 0 0\n" |
|
41 |
"9 0 3 0\n" |
|
42 |
"10 0 -2 0\n" |
|
43 |
"11 0 0 0\n" |
|
44 |
"12 0 -20 -27\n" |
|
45 |
"@arcs\n" |
|
46 |
" cost capacity lower1 lower2\n" |
|
47 |
" 1 2 70 11 0 8\n" |
|
48 |
" 1 3 150 3 0 1\n" |
|
49 |
" 1 4 80 15 0 2\n" |
|
50 |
" 2 8 80 12 0 0\n" |
|
51 |
" 3 5 140 5 0 3\n" |
|
52 |
" 4 6 60 10 0 1\n" |
|
53 |
" 4 7 80 2 0 0\n" |
|
54 |
" 4 8 110 3 0 0\n" |
|
55 |
" 5 7 60 14 0 0\n" |
|
56 |
" 5 11 120 12 0 0\n" |
|
57 |
" 6 3 0 3 0 0\n" |
|
58 |
" 6 9 140 4 0 0\n" |
|
59 |
" 6 10 90 8 0 0\n" |
|
60 |
" 7 1 30 5 0 0\n" |
|
61 |
" 8 12 60 16 0 4\n" |
|
62 |
" 9 12 50 6 0 0\n" |
|
63 |
"10 12 70 13 0 5\n" |
|
64 |
"10 2 100 7 0 0\n" |
|
65 |
"10 7 60 10 0 0\n" |
|
66 |
"11 10 20 14 0 6\n" |
|
67 |
"12 11 30 10 0 0\n" |
|
68 |
"@attributes\n" |
|
69 |
"source 1\n" |
|
70 |
"target 12\n" |
|
71 |
"@end\n"; |
|
72 |
|
|
31 | 73 |
// Check the feasibility of the flow |
32 | 74 |
template <typename Digraph, typename FlowMap> |
33 | 75 |
bool checkFlow( const Digraph& gr, const FlowMap& flow, |
34 | 76 |
typename Digraph::Node s, typename Digraph::Node t, |
35 | 77 |
int value ) |
36 | 78 |
{ |
37 | 79 |
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); |
38 | 80 |
for (ArcIt e(gr); e != INVALID; ++e) |
39 | 81 |
if (!(flow[e] == 0 || flow[e] == 1)) return false; |
40 | 82 |
|
41 | 83 |
for (NodeIt n(gr); n != INVALID; ++n) { |
42 | 84 |
int sum = 0; |
43 | 85 |
for (OutArcIt e(gr, n); e != INVALID; ++e) |
44 | 86 |
sum += flow[e]; |
45 | 87 |
for (InArcIt e(gr, n); e != INVALID; ++e) |
46 | 88 |
sum -= flow[e]; |
47 | 89 |
if (n == s && sum != value) return false; |
48 | 90 |
if (n == t && sum != -value) return false; |
49 | 91 |
if (n != s && n != t && sum != 0) return false; |
50 | 92 |
} |
51 | 93 |
|
52 | 94 |
return true; |
53 | 95 |
} |
54 | 96 |
|
55 | 97 |
// Check the optimalitiy of the flow |
56 | 98 |
template < typename Digraph, typename CostMap, |
57 | 99 |
typename FlowMap, typename PotentialMap > |
58 | 100 |
bool checkOptimality( const Digraph& gr, const CostMap& cost, |
59 | 101 |
const FlowMap& flow, const PotentialMap& pi ) |
60 | 102 |
{ |
61 | 103 |
// Check the "Complementary Slackness" optimality condition |
62 | 104 |
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); |
63 | 105 |
bool opt = true; |
64 | 106 |
for (ArcIt e(gr); e != INVALID; ++e) { |
65 | 107 |
typename CostMap::Value red_cost = |
66 | 108 |
cost[e] + pi[gr.source(e)] - pi[gr.target(e)]; |
67 | 109 |
opt = (flow[e] == 0 && red_cost >= 0) || |
68 | 110 |
(flow[e] == 1 && red_cost <= 0); |
69 | 111 |
if (!opt) break; |
70 | 112 |
} |
71 | 113 |
return opt; |
72 | 114 |
} |
73 | 115 |
|
74 | 116 |
// Check a path |
75 | 117 |
template <typename Digraph, typename Path> |
76 | 118 |
bool checkPath( const Digraph& gr, const Path& path, |
77 | 119 |
typename Digraph::Node s, typename Digraph::Node t) |
78 | 120 |
{ |
79 | 121 |
// Check the "Complementary Slackness" optimality condition |
80 | 122 |
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); |
81 | 123 |
Node n = s; |
82 | 124 |
for (int i = 0; i < path.length(); ++i) { |
83 | 125 |
if (gr.source(path.nth(i)) != n) return false; |
84 | 126 |
n = gr.target(path.nth(i)); |
85 | 127 |
} |
86 | 128 |
return n == t; |
87 | 129 |
} |
88 | 130 |
|
89 | 131 |
|
90 | 132 |
int main() |
91 | 133 |
{ |
92 | 134 |
DIGRAPH_TYPEDEFS(ListDigraph); |
93 | 135 |
|
94 | 136 |
// Read the test digraph |
95 | 137 |
ListDigraph digraph; |
96 | 138 |
ListDigraph::ArcMap<int> length(digraph); |
97 | 139 |
Node source, target; |
98 | 140 |
|
99 |
std::string fname; |
|
100 |
if(getenv("srcdir")) |
|
101 |
fname = std::string(getenv("srcdir")); |
|
102 |
else fname = "."; |
|
103 |
fname += "/test/min_cost_flow_test.lgf"; |
|
104 |
|
|
105 |
std::ifstream input(fname.c_str()); |
|
106 |
check(input, "Input file '" << fname << "' not found"); |
|
141 |
std::istringstream input(test_lgf); |
|
107 | 142 |
DigraphReader<ListDigraph>(digraph, input). |
108 | 143 |
arcMap("cost", length). |
109 | 144 |
node("source", source). |
110 | 145 |
node("target", target). |
111 | 146 |
run(); |
112 |
input.close(); |
|
113 | 147 |
|
114 | 148 |
// Find 2 paths |
115 | 149 |
{ |
116 | 150 |
Suurballe<ListDigraph> suurballe(digraph, length, source, target); |
117 | 151 |
check(suurballe.run(2) == 2, "Wrong number of paths"); |
118 | 152 |
check(checkFlow(digraph, suurballe.flowMap(), source, target, 2), |
119 | 153 |
"The flow is not feasible"); |
120 | 154 |
check(suurballe.totalLength() == 510, "The flow is not optimal"); |
121 | 155 |
check(checkOptimality(digraph, length, suurballe.flowMap(), |
122 | 156 |
suurballe.potentialMap()), |
123 | 157 |
"Wrong potentials"); |
124 | 158 |
for (int i = 0; i < suurballe.pathNum(); ++i) |
125 | 159 |
check(checkPath(digraph, suurballe.path(i), source, target), |
126 | 160 |
"Wrong path"); |
127 | 161 |
} |
128 | 162 |
|
129 | 163 |
// Find 3 paths |
130 | 164 |
{ |
131 | 165 |
Suurballe<ListDigraph> suurballe(digraph, length, source, target); |
132 | 166 |
check(suurballe.run(3) == 3, "Wrong number of paths"); |
133 | 167 |
check(checkFlow(digraph, suurballe.flowMap(), source, target, 3), |
134 | 168 |
"The flow is not feasible"); |
135 | 169 |
check(suurballe.totalLength() == 1040, "The flow is not optimal"); |
136 | 170 |
check(checkOptimality(digraph, length, suurballe.flowMap(), |
137 | 171 |
suurballe.potentialMap()), |
138 | 172 |
"Wrong potentials"); |
139 | 173 |
for (int i = 0; i < suurballe.pathNum(); ++i) |
140 | 174 |
check(checkPath(digraph, suurballe.path(i), source, target), |
141 | 175 |
"Wrong path"); |
142 | 176 |
} |
143 | 177 |
|
144 | 178 |
// Find 5 paths (only 3 can be found) |
145 | 179 |
{ |
146 | 180 |
Suurballe<ListDigraph> suurballe(digraph, length, source, target); |
147 | 181 |
check(suurballe.run(5) == 3, "Wrong number of paths"); |
148 | 182 |
check(checkFlow(digraph, suurballe.flowMap(), source, target, 3), |
149 | 183 |
"The flow is not feasible"); |
150 | 184 |
check(suurballe.totalLength() == 1040, "The flow is not optimal"); |
151 | 185 |
check(checkOptimality(digraph, length, suurballe.flowMap(), |
152 | 186 |
suurballe.potentialMap()), |
153 | 187 |
"Wrong potentials"); |
154 | 188 |
for (int i = 0; i < suurballe.pathNum(); ++i) |
155 | 189 |
check(checkPath(digraph, suurballe.path(i), source, target), |
156 | 190 |
"Wrong path"); |
157 | 191 |
} |
158 | 192 |
|
159 | 193 |
return 0; |
160 | 194 |
} |
1 |
@nodes |
|
2 |
label supply1 supply2 supply3 |
|
3 |
1 0 20 27 |
|
4 |
2 0 -4 0 |
|
5 |
3 0 0 0 |
|
6 |
4 0 0 0 |
|
7 |
5 0 9 0 |
|
8 |
6 0 -6 0 |
|
9 |
7 0 0 0 |
|
10 |
8 0 0 0 |
|
11 |
9 0 3 0 |
|
12 |
10 0 -2 0 |
|
13 |
11 0 0 0 |
|
14 |
12 0 -20 -27 |
|
15 |
|
|
16 |
@arcs |
|
17 |
cost capacity lower1 lower2 |
|
18 |
1 2 70 11 0 8 |
|
19 |
1 3 150 3 0 1 |
|
20 |
1 4 80 15 0 2 |
|
21 |
2 8 80 12 0 0 |
|
22 |
3 5 140 5 0 3 |
|
23 |
4 6 60 10 0 1 |
|
24 |
4 7 80 2 0 0 |
|
25 |
4 8 110 3 0 0 |
|
26 |
5 7 60 14 0 0 |
|
27 |
5 11 120 12 0 0 |
|
28 |
6 3 0 3 0 0 |
|
29 |
6 9 140 4 0 0 |
|
30 |
6 10 90 8 0 0 |
|
31 |
7 1 30 5 0 0 |
|
32 |
8 12 60 16 0 4 |
|
33 |
9 12 50 6 0 0 |
|
34 |
10 12 70 13 0 5 |
|
35 |
10 2 100 7 0 0 |
|
36 |
10 7 60 10 0 0 |
|
37 |
11 10 20 14 0 6 |
|
38 |
12 11 30 10 0 0 |
|
39 |
|
|
40 |
@attributes |
|
41 |
source 1 |
|
42 |
target 12 |
|
43 |
|
|
44 |
@end |
1 |
@nodes |
|
2 |
label |
|
3 |
0 |
|
4 |
1 |
|
5 |
2 |
|
6 |
3 |
|
7 |
4 |
|
8 |
5 |
|
9 |
6 |
|
10 |
7 |
|
11 |
8 |
|
12 |
9 |
|
13 |
@arcs |
|
14 |
label capacity |
|
15 |
0 1 0 20 |
|
16 |
0 2 1 0 |
|
17 |
1 1 2 3 |
|
18 |
1 2 3 8 |
|
19 |
1 3 4 8 |
|
20 |
2 5 5 5 |
|
21 |
3 2 6 5 |
|
22 |
3 5 7 5 |
|
23 |
3 6 8 5 |
|
24 |
4 3 9 3 |
|
25 |
5 7 10 3 |
|
26 |
5 6 11 10 |
|
27 |
5 8 12 10 |
|
28 |
6 8 13 8 |
|
29 |
8 9 14 20 |
|
30 |
8 1 15 5 |
|
31 |
9 5 16 5 |
|
32 |
@attributes |
|
33 |
source 1 |
|
34 |
target 8 |
0 comments (0 inline)