1 /* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 * |
|
3 * This file is a part of LEMON, a generic C++ optimization library. |
|
4 * |
|
5 * Copyright (C) 2003-2010 |
|
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
|
8 * |
|
9 * Permission to use, modify and distribute this software is granted |
|
10 * provided that this copyright notice appears in all copies. For |
|
11 * precise terms see the accompanying LICENSE file. |
|
12 * |
|
13 * This software is provided "AS IS" with no warranty of any kind, |
|
14 * express or implied, and with no claim as to its suitability for any |
|
15 * purpose. |
|
16 * |
|
17 */ |
|
18 |
|
19 #include <iostream> |
|
20 |
|
21 #include "test_tools.h" |
|
22 #include <lemon/smart_graph.h> |
|
23 #include <lemon/preflow.h> |
|
24 #include <lemon/concepts/digraph.h> |
|
25 #include <lemon/concepts/maps.h> |
|
26 #include <lemon/lgf_reader.h> |
|
27 #include <lemon/elevator.h> |
|
28 |
|
29 using namespace lemon; |
|
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 |
|
67 void checkPreflowCompile() |
|
68 { |
|
69 typedef int VType; |
|
70 typedef concepts::Digraph Digraph; |
|
71 |
|
72 typedef Digraph::Node Node; |
|
73 typedef Digraph::Arc Arc; |
|
74 typedef concepts::ReadMap<Arc,VType> CapMap; |
|
75 typedef concepts::ReadWriteMap<Arc,VType> FlowMap; |
|
76 typedef concepts::WriteMap<Node,bool> CutMap; |
|
77 |
|
78 typedef Elevator<Digraph, Digraph::Node> Elev; |
|
79 typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev; |
|
80 |
|
81 Digraph g; |
|
82 Node n; |
|
83 Arc e; |
|
84 CapMap cap; |
|
85 FlowMap flow; |
|
86 CutMap cut; |
|
87 VType v; |
|
88 bool b; |
|
89 |
|
90 typedef Preflow<Digraph, CapMap> |
|
91 ::SetFlowMap<FlowMap> |
|
92 ::SetElevator<Elev> |
|
93 ::SetStandardElevator<LinkedElev> |
|
94 ::Create PreflowType; |
|
95 PreflowType preflow_test(g, cap, n, n); |
|
96 const PreflowType& const_preflow_test = preflow_test; |
|
97 |
|
98 const PreflowType::Elevator& elev = const_preflow_test.elevator(); |
|
99 preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev)); |
|
100 PreflowType::Tolerance tol = const_preflow_test.tolerance(); |
|
101 preflow_test.tolerance(tol); |
|
102 |
|
103 preflow_test |
|
104 .capacityMap(cap) |
|
105 .flowMap(flow) |
|
106 .source(n) |
|
107 .target(n); |
|
108 |
|
109 preflow_test.init(); |
|
110 preflow_test.init(cap); |
|
111 preflow_test.startFirstPhase(); |
|
112 preflow_test.startSecondPhase(); |
|
113 preflow_test.run(); |
|
114 preflow_test.runMinCut(); |
|
115 |
|
116 v = const_preflow_test.flowValue(); |
|
117 v = const_preflow_test.flow(e); |
|
118 const FlowMap& fm = const_preflow_test.flowMap(); |
|
119 b = const_preflow_test.minCut(n); |
|
120 const_preflow_test.minCutMap(cut); |
|
121 |
|
122 ignore_unused_variable_warning(fm); |
|
123 } |
|
124 |
|
125 int cutValue (const SmartDigraph& g, |
|
126 const SmartDigraph::NodeMap<bool>& cut, |
|
127 const SmartDigraph::ArcMap<int>& cap) { |
|
128 |
|
129 int c=0; |
|
130 for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) { |
|
131 if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e]; |
|
132 } |
|
133 return c; |
|
134 } |
|
135 |
|
136 bool checkFlow(const SmartDigraph& g, |
|
137 const SmartDigraph::ArcMap<int>& flow, |
|
138 const SmartDigraph::ArcMap<int>& cap, |
|
139 SmartDigraph::Node s, SmartDigraph::Node t) { |
|
140 |
|
141 for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) { |
|
142 if (flow[e] < 0 || flow[e] > cap[e]) return false; |
|
143 } |
|
144 |
|
145 for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) { |
|
146 if (n == s || n == t) continue; |
|
147 int sum = 0; |
|
148 for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) { |
|
149 sum += flow[e]; |
|
150 } |
|
151 for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) { |
|
152 sum -= flow[e]; |
|
153 } |
|
154 if (sum != 0) return false; |
|
155 } |
|
156 return true; |
|
157 } |
|
158 |
|
159 void initFlowTest() |
|
160 { |
|
161 DIGRAPH_TYPEDEFS(SmartDigraph); |
|
162 |
|
163 SmartDigraph g; |
|
164 SmartDigraph::ArcMap<int> cap(g),iflow(g); |
|
165 Node s=g.addNode(); Node t=g.addNode(); |
|
166 Node n1=g.addNode(); Node n2=g.addNode(); |
|
167 Arc a; |
|
168 a=g.addArc(s,n1); cap[a]=20; iflow[a]=20; |
|
169 a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0; |
|
170 a=g.addArc(n2,t); cap[a]=20; iflow[a]=0; |
|
171 |
|
172 Preflow<SmartDigraph> pre(g,cap,s,t); |
|
173 pre.init(iflow); |
|
174 pre.startFirstPhase(); |
|
175 check(pre.flowValue() == 10, "The incorrect max flow value."); |
|
176 check(pre.minCut(s), "Wrong min cut (Node s)."); |
|
177 check(pre.minCut(n1), "Wrong min cut (Node n1)."); |
|
178 check(!pre.minCut(n2), "Wrong min cut (Node n2)."); |
|
179 check(!pre.minCut(t), "Wrong min cut (Node t)."); |
|
180 } |
|
181 |
|
182 |
|
183 int main() { |
|
184 |
|
185 typedef SmartDigraph Digraph; |
|
186 |
|
187 typedef Digraph::Node Node; |
|
188 typedef Digraph::NodeIt NodeIt; |
|
189 typedef Digraph::ArcIt ArcIt; |
|
190 typedef Digraph::ArcMap<int> CapMap; |
|
191 typedef Digraph::ArcMap<int> FlowMap; |
|
192 typedef Digraph::NodeMap<bool> CutMap; |
|
193 |
|
194 typedef Preflow<Digraph, CapMap> PType; |
|
195 |
|
196 Digraph g; |
|
197 Node s, t; |
|
198 CapMap cap(g); |
|
199 std::istringstream input(test_lgf); |
|
200 DigraphReader<Digraph>(g,input). |
|
201 arcMap("capacity", cap). |
|
202 node("source",s). |
|
203 node("target",t). |
|
204 run(); |
|
205 |
|
206 PType preflow_test(g, cap, s, t); |
|
207 preflow_test.run(); |
|
208 |
|
209 check(checkFlow(g, preflow_test.flowMap(), cap, s, t), |
|
210 "The flow is not feasible."); |
|
211 |
|
212 CutMap min_cut(g); |
|
213 preflow_test.minCutMap(min_cut); |
|
214 int min_cut_value=cutValue(g,min_cut,cap); |
|
215 |
|
216 check(preflow_test.flowValue() == min_cut_value, |
|
217 "The max flow value is not equal to the three min cut values."); |
|
218 |
|
219 FlowMap flow(g); |
|
220 for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e]; |
|
221 |
|
222 int flow_value=preflow_test.flowValue(); |
|
223 |
|
224 for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e]; |
|
225 preflow_test.init(flow); |
|
226 preflow_test.startFirstPhase(); |
|
227 |
|
228 CutMap min_cut1(g); |
|
229 preflow_test.minCutMap(min_cut1); |
|
230 min_cut_value=cutValue(g,min_cut1,cap); |
|
231 |
|
232 check(preflow_test.flowValue() == min_cut_value && |
|
233 min_cut_value == 2*flow_value, |
|
234 "The max flow value or the min cut value is wrong."); |
|
235 |
|
236 preflow_test.startSecondPhase(); |
|
237 |
|
238 check(checkFlow(g, preflow_test.flowMap(), cap, s, t), |
|
239 "The flow is not feasible."); |
|
240 |
|
241 CutMap min_cut2(g); |
|
242 preflow_test.minCutMap(min_cut2); |
|
243 min_cut_value=cutValue(g,min_cut2,cap); |
|
244 |
|
245 check(preflow_test.flowValue() == min_cut_value && |
|
246 min_cut_value == 2*flow_value, |
|
247 "The max flow value or the three min cut values were not doubled"); |
|
248 |
|
249 |
|
250 preflow_test.flowMap(flow); |
|
251 |
|
252 NodeIt tmp1(g,s); |
|
253 ++tmp1; |
|
254 if ( tmp1 != INVALID ) s=tmp1; |
|
255 |
|
256 NodeIt tmp2(g,t); |
|
257 ++tmp2; |
|
258 if ( tmp2 != INVALID ) t=tmp2; |
|
259 |
|
260 preflow_test.source(s); |
|
261 preflow_test.target(t); |
|
262 |
|
263 preflow_test.run(); |
|
264 |
|
265 CutMap min_cut3(g); |
|
266 preflow_test.minCutMap(min_cut3); |
|
267 min_cut_value=cutValue(g,min_cut3,cap); |
|
268 |
|
269 |
|
270 check(preflow_test.flowValue() == min_cut_value, |
|
271 "The max flow value or the three min cut values are incorrect."); |
|
272 |
|
273 initFlowTest(); |
|
274 |
|
275 return 0; |
|
276 } |
|