| [389] | 1 | /* -*- mode: C++; indent-tabs-mode: nil; -*- | 
|---|
 | 2 |  * | 
|---|
 | 3 |  * This file is a part of LEMON, a generic C++ optimization library. | 
|---|
 | 4 |  * | 
|---|
| [1092] | 5 |  * Copyright (C) 2003-2013 | 
|---|
| [389] | 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 |  | 
|---|
| [423] | 19 | #include <iostream> | 
|---|
| [389] | 20 |  | 
|---|
 | 21 | #include "test_tools.h" | 
|---|
 | 22 | #include <lemon/smart_graph.h> | 
|---|
 | 23 | #include <lemon/preflow.h> | 
|---|
| [1060] | 24 | #include <lemon/edmonds_karp.h> | 
|---|
| [389] | 25 | #include <lemon/concepts/digraph.h> | 
|---|
 | 26 | #include <lemon/concepts/maps.h> | 
|---|
 | 27 | #include <lemon/lgf_reader.h> | 
|---|
| [394] | 28 | #include <lemon/elevator.h> | 
|---|
| [1167] | 29 | #include <lemon/tolerance.h> | 
|---|
| [389] | 30 |  | 
|---|
 | 31 | using namespace lemon; | 
|---|
 | 32 |  | 
|---|
| [423] | 33 | char test_lgf[] = | 
|---|
 | 34 |   "@nodes\n" | 
|---|
 | 35 |   "label\n" | 
|---|
 | 36 |   "0\n" | 
|---|
 | 37 |   "1\n" | 
|---|
 | 38 |   "2\n" | 
|---|
 | 39 |   "3\n" | 
|---|
 | 40 |   "4\n" | 
|---|
 | 41 |   "5\n" | 
|---|
 | 42 |   "6\n" | 
|---|
 | 43 |   "7\n" | 
|---|
 | 44 |   "8\n" | 
|---|
 | 45 |   "9\n" | 
|---|
 | 46 |   "@arcs\n" | 
|---|
 | 47 |   "    label capacity\n" | 
|---|
 | 48 |   "0 1 0     20\n" | 
|---|
 | 49 |   "0 2 1     0\n" | 
|---|
 | 50 |   "1 1 2     3\n" | 
|---|
 | 51 |   "1 2 3     8\n" | 
|---|
 | 52 |   "1 3 4     8\n" | 
|---|
 | 53 |   "2 5 5     5\n" | 
|---|
 | 54 |   "3 2 6     5\n" | 
|---|
 | 55 |   "3 5 7     5\n" | 
|---|
 | 56 |   "3 6 8     5\n" | 
|---|
 | 57 |   "4 3 9     3\n" | 
|---|
 | 58 |   "5 7 10    3\n" | 
|---|
 | 59 |   "5 6 11    10\n" | 
|---|
 | 60 |   "5 8 12    10\n" | 
|---|
 | 61 |   "6 8 13    8\n" | 
|---|
 | 62 |   "8 9 14    20\n" | 
|---|
 | 63 |   "8 1 15    5\n" | 
|---|
 | 64 |   "9 5 16    5\n" | 
|---|
 | 65 |   "@attributes\n" | 
|---|
 | 66 |   "source 1\n" | 
|---|
 | 67 |   "target 8\n"; | 
|---|
 | 68 |  | 
|---|
| [1169] | 69 | char test_lgf_float[] = | 
|---|
 | 70 |   "@nodes\n" | 
|---|
 | 71 |   "label\n" | 
|---|
 | 72 |   "0\n" | 
|---|
 | 73 |   "1\n" | 
|---|
 | 74 |   "2\n" | 
|---|
 | 75 |   "3\n" | 
|---|
 | 76 |   "4\n" | 
|---|
 | 77 |   "5\n" | 
|---|
 | 78 |   "6\n" | 
|---|
 | 79 |   "7\n" | 
|---|
 | 80 |   "8\n" | 
|---|
 | 81 |   "9\n" | 
|---|
 | 82 |   "@arcs\n" | 
|---|
 | 83 |   "      capacity\n" | 
|---|
 | 84 |   "0 1 0.1\n" | 
|---|
 | 85 |   "0 2 0.1\n" | 
|---|
 | 86 |   "0 3 0.1\n" | 
|---|
 | 87 |   "1 4 0.1\n" | 
|---|
 | 88 |   "2 4 0.1\n" | 
|---|
 | 89 |   "3 4 0.1\n" | 
|---|
 | 90 |   "4 5 0.3\n" | 
|---|
 | 91 |   "5 6 0.1\n" | 
|---|
 | 92 |   "5 7 0.1\n" | 
|---|
 | 93 |   "5 8 0.1\n" | 
|---|
 | 94 |   "6 9 0.1\n" | 
|---|
 | 95 |   "7 9 0.1\n" | 
|---|
 | 96 |   "8 9 0.1\n" | 
|---|
 | 97 |   "@attributes\n" | 
|---|
 | 98 |   "source 0\n" | 
|---|
 | 99 |   "target 9\n"; | 
|---|
 | 100 |  | 
|---|
| [1060] | 101 | // Checks the general interface of a max flow algorithm | 
|---|
 | 102 | template <typename GR, typename CAP> | 
|---|
 | 103 | struct MaxFlowClassConcept | 
|---|
 | 104 | { | 
|---|
 | 105 |  | 
|---|
 | 106 |   template <typename MF> | 
|---|
 | 107 |   struct Constraints { | 
|---|
 | 108 |  | 
|---|
 | 109 |     typedef typename GR::Node Node; | 
|---|
 | 110 |     typedef typename GR::Arc Arc; | 
|---|
 | 111 |     typedef typename CAP::Value Value; | 
|---|
 | 112 |     typedef concepts::ReadWriteMap<Arc, Value> FlowMap; | 
|---|
 | 113 |     typedef concepts::WriteMap<Node, bool> CutMap; | 
|---|
 | 114 |  | 
|---|
 | 115 |     GR g; | 
|---|
 | 116 |     Node n; | 
|---|
 | 117 |     Arc e; | 
|---|
 | 118 |     CAP cap; | 
|---|
 | 119 |     FlowMap flow; | 
|---|
 | 120 |     CutMap cut; | 
|---|
 | 121 |     Value v; | 
|---|
 | 122 |     bool b; | 
|---|
 | 123 |  | 
|---|
 | 124 |     void constraints() { | 
|---|
 | 125 |       checkConcept<concepts::Digraph, GR>(); | 
|---|
 | 126 |  | 
|---|
 | 127 |       const Constraints& me = *this; | 
|---|
 | 128 |  | 
|---|
 | 129 |       typedef typename MF | 
|---|
 | 130 |           ::template SetFlowMap<FlowMap> | 
|---|
 | 131 |           ::Create MaxFlowType; | 
|---|
 | 132 |       typedef typename MF::Create MaxFlowType2; | 
|---|
 | 133 |       MaxFlowType max_flow(me.g, me.cap, me.n, me.n); | 
|---|
 | 134 |       const MaxFlowType& const_max_flow = max_flow; | 
|---|
 | 135 |  | 
|---|
 | 136 |       max_flow | 
|---|
 | 137 |           .capacityMap(cap) | 
|---|
 | 138 |           .flowMap(flow) | 
|---|
 | 139 |           .source(n) | 
|---|
 | 140 |           .target(n); | 
|---|
 | 141 |  | 
|---|
 | 142 |       typename MaxFlowType::Tolerance tol = const_max_flow.tolerance(); | 
|---|
 | 143 |       max_flow.tolerance(tol); | 
|---|
 | 144 |  | 
|---|
 | 145 |       max_flow.init(); | 
|---|
 | 146 |       max_flow.init(cap); | 
|---|
 | 147 |       max_flow.run(); | 
|---|
 | 148 |  | 
|---|
 | 149 |       v = const_max_flow.flowValue(); | 
|---|
 | 150 |       v = const_max_flow.flow(e); | 
|---|
 | 151 |       const FlowMap& fm = const_max_flow.flowMap(); | 
|---|
 | 152 |  | 
|---|
 | 153 |       b = const_max_flow.minCut(n); | 
|---|
 | 154 |       const_max_flow.minCutMap(cut); | 
|---|
 | 155 |  | 
|---|
| [1087] | 156 |       ::lemon::ignore_unused_variable_warning(fm); | 
|---|
| [1060] | 157 |     } | 
|---|
 | 158 |  | 
|---|
 | 159 |   }; | 
|---|
 | 160 |  | 
|---|
 | 161 | }; | 
|---|
 | 162 |  | 
|---|
 | 163 | // Checks the specific parts of Preflow's interface | 
|---|
| [394] | 164 | void checkPreflowCompile() | 
|---|
| [389] | 165 | { | 
|---|
| [1060] | 166 |   typedef int Value; | 
|---|
| [389] | 167 |   typedef concepts::Digraph Digraph; | 
|---|
| [1060] | 168 |   typedef concepts::ReadMap<Digraph::Arc, Value> CapMap; | 
|---|
| [394] | 169 |   typedef Elevator<Digraph, Digraph::Node> Elev; | 
|---|
 | 170 |   typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev; | 
|---|
 | 171 |  | 
|---|
| [389] | 172 |   Digraph g; | 
|---|
| [1060] | 173 |   Digraph::Node n; | 
|---|
| [389] | 174 |   CapMap cap; | 
|---|
 | 175 |  | 
|---|
| [585] | 176 |   typedef Preflow<Digraph, CapMap> | 
|---|
| [1060] | 177 |       ::SetElevator<Elev> | 
|---|
 | 178 |       ::SetStandardElevator<LinkedElev> | 
|---|
 | 179 |       ::Create PreflowType; | 
|---|
| [585] | 180 |   PreflowType preflow_test(g, cap, n, n); | 
|---|
 | 181 |   const PreflowType& const_preflow_test = preflow_test; | 
|---|
| [389] | 182 |  | 
|---|
| [689] | 183 |   const PreflowType::Elevator& elev = const_preflow_test.elevator(); | 
|---|
 | 184 |   preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev)); | 
|---|
| [585] | 185 |  | 
|---|
| [1060] | 186 |   bool b = preflow_test.init(cap); | 
|---|
| [389] | 187 |   preflow_test.startFirstPhase(); | 
|---|
 | 188 |   preflow_test.startSecondPhase(); | 
|---|
 | 189 |   preflow_test.runMinCut(); | 
|---|
 | 190 |  | 
|---|
| [1087] | 191 |   ::lemon::ignore_unused_variable_warning(b); | 
|---|
| [389] | 192 | } | 
|---|
 | 193 |  | 
|---|
| [1060] | 194 | // Checks the specific parts of EdmondsKarp's interface | 
|---|
 | 195 | void checkEdmondsKarpCompile() | 
|---|
 | 196 | { | 
|---|
 | 197 |   typedef int Value; | 
|---|
 | 198 |   typedef concepts::Digraph Digraph; | 
|---|
 | 199 |   typedef concepts::ReadMap<Digraph::Arc, Value> CapMap; | 
|---|
 | 200 |  | 
|---|
 | 201 |   Digraph g; | 
|---|
 | 202 |   Digraph::Node n; | 
|---|
 | 203 |   CapMap cap; | 
|---|
 | 204 |  | 
|---|
 | 205 |   EdmondsKarp<Digraph, CapMap> ek_test(g, cap, n, n); | 
|---|
 | 206 |  | 
|---|
 | 207 |   ek_test.init(cap); | 
|---|
 | 208 |   bool b = ek_test.checkedInit(cap); | 
|---|
 | 209 |   b = ek_test.augment(); | 
|---|
 | 210 |   ek_test.start(); | 
|---|
 | 211 |  | 
|---|
| [1087] | 212 |   ::lemon::ignore_unused_variable_warning(b); | 
|---|
| [1060] | 213 | } | 
|---|
 | 214 |  | 
|---|
 | 215 |  | 
|---|
 | 216 | template <typename T> | 
|---|
| [1166] | 217 | T cutValue(const SmartDigraph& g, | 
|---|
 | 218 |            const SmartDigraph::NodeMap<bool>& cut, | 
|---|
 | 219 |            const SmartDigraph::ArcMap<T>& cap) { | 
|---|
| [389] | 220 |  | 
|---|
| [1166] | 221 |   T c = 0; | 
|---|
 | 222 |   for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) { | 
|---|
 | 223 |     if (cut[g.source(e)] && !cut[g.target(e)]) c += cap[e]; | 
|---|
| [389] | 224 |   } | 
|---|
 | 225 |   return c; | 
|---|
 | 226 | } | 
|---|
 | 227 |  | 
|---|
| [1060] | 228 | template <typename T> | 
|---|
| [389] | 229 | bool checkFlow(const SmartDigraph& g, | 
|---|
| [1060] | 230 |                const SmartDigraph::ArcMap<T>& flow, | 
|---|
 | 231 |                const SmartDigraph::ArcMap<T>& cap, | 
|---|
| [1167] | 232 |                SmartDigraph::Node s, SmartDigraph::Node t, | 
|---|
 | 233 |                const Tolerance<T>& tol) { | 
|---|
| [389] | 234 |  | 
|---|
 | 235 |   for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) { | 
|---|
| [1167] | 236 |     if (tol.negative(flow[e]) || tol.less(cap[e], flow[e])) return false; | 
|---|
| [389] | 237 |   } | 
|---|
 | 238 |  | 
|---|
 | 239 |   for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) { | 
|---|
 | 240 |     if (n == s || n == t) continue; | 
|---|
| [1060] | 241 |     T sum = 0; | 
|---|
| [389] | 242 |     for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) { | 
|---|
 | 243 |       sum += flow[e]; | 
|---|
 | 244 |     } | 
|---|
 | 245 |     for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) { | 
|---|
 | 246 |       sum -= flow[e]; | 
|---|
 | 247 |     } | 
|---|
| [1167] | 248 |     if (tol.nonZero(sum)) return false; | 
|---|
| [389] | 249 |   } | 
|---|
 | 250 |   return true; | 
|---|
 | 251 | } | 
|---|
 | 252 |  | 
|---|
| [1166] | 253 | void checkInitPreflow() | 
|---|
| [923] | 254 | { | 
|---|
 | 255 |   DIGRAPH_TYPEDEFS(SmartDigraph); | 
|---|
| [1092] | 256 |  | 
|---|
| [923] | 257 |   SmartDigraph g; | 
|---|
| [1166] | 258 |   SmartDigraph::ArcMap<int> cap(g), iflow(g); | 
|---|
 | 259 |   Node s = g.addNode(); Node t = g.addNode(); | 
|---|
 | 260 |   Node n1 = g.addNode(); Node n2 = g.addNode(); | 
|---|
| [923] | 261 |   Arc a; | 
|---|
| [1166] | 262 |   a = g.addArc(s, n1); cap[a] = 20; iflow[a] = 20; | 
|---|
 | 263 |   a = g.addArc(n1, n2); cap[a] = 10; iflow[a] = 0; | 
|---|
 | 264 |   a = g.addArc(n2, t); cap[a] = 20; iflow[a] = 0; | 
|---|
| [923] | 265 |  | 
|---|
| [1166] | 266 |   Preflow<SmartDigraph> pre(g, cap, s, t); | 
|---|
| [923] | 267 |   pre.init(iflow); | 
|---|
 | 268 |   pre.startFirstPhase(); | 
|---|
| [1166] | 269 |  | 
|---|
 | 270 |   check(pre.flowValue() == 10, "Incorrect max flow value."); | 
|---|
| [923] | 271 |   check(pre.minCut(s), "Wrong min cut (Node s)."); | 
|---|
 | 272 |   check(pre.minCut(n1), "Wrong min cut (Node n1)."); | 
|---|
 | 273 |   check(!pre.minCut(n2), "Wrong min cut (Node n2)."); | 
|---|
 | 274 |   check(!pre.minCut(t), "Wrong min cut (Node t)."); | 
|---|
 | 275 | } | 
|---|
 | 276 |  | 
|---|
| [1060] | 277 | template <typename MF, typename SF> | 
|---|
| [1168] | 278 | void checkMaxFlowAlg(const char *input_lgf,  typename MF::Value expected) { | 
|---|
| [1060] | 279 |   typedef SmartDigraph Digraph; | 
|---|
 | 280 |   DIGRAPH_TYPEDEFS(Digraph); | 
|---|
| [923] | 281 |  | 
|---|
| [1060] | 282 |   typedef typename MF::Value Value; | 
|---|
 | 283 |   typedef Digraph::ArcMap<Value> CapMap; | 
|---|
 | 284 |   typedef CapMap FlowMap; | 
|---|
 | 285 |   typedef BoolNodeMap CutMap; | 
|---|
| [389] | 286 |  | 
|---|
| [1167] | 287 |   Tolerance<Value> tol; | 
|---|
 | 288 |  | 
|---|
| [389] | 289 |   Digraph g; | 
|---|
 | 290 |   Node s, t; | 
|---|
 | 291 |   CapMap cap(g); | 
|---|
| [1168] | 292 |   std::istringstream input(input_lgf); | 
|---|
| [1169] | 293 |   DigraphReader<Digraph>(g, input) | 
|---|
| [1060] | 294 |       .arcMap("capacity", cap) | 
|---|
| [1169] | 295 |       .node("source", s) | 
|---|
 | 296 |       .node("target", t) | 
|---|
| [1060] | 297 |       .run(); | 
|---|
| [389] | 298 |  | 
|---|
| [1060] | 299 |   MF max_flow(g, cap, s, t); | 
|---|
 | 300 |   max_flow.run(); | 
|---|
| [389] | 301 |  | 
|---|
| [1168] | 302 |   check(!tol.different(expected, max_flow.flowValue()), | 
|---|
 | 303 |         "Incorrect max flow value."); | 
|---|
| [1167] | 304 |   check(checkFlow(g, max_flow.flowMap(), cap, s, t, tol), | 
|---|
| [389] | 305 |         "The flow is not feasible."); | 
|---|
 | 306 |  | 
|---|
 | 307 |   CutMap min_cut(g); | 
|---|
| [1060] | 308 |   max_flow.minCutMap(min_cut); | 
|---|
 | 309 |   Value min_cut_value = cutValue(g, min_cut, cap); | 
|---|
| [389] | 310 |  | 
|---|
| [1168] | 311 |   check(!tol.different(expected, min_cut_value), | 
|---|
 | 312 |         "Incorrect min cut value."); | 
|---|
| [389] | 313 |  | 
|---|
 | 314 |   FlowMap flow(g); | 
|---|
| [1169] | 315 |   for (ArcIt e(g); e != INVALID; ++e) flow[e] = 13 * max_flow.flowMap()[e]; | 
|---|
 | 316 |   for (ArcIt e(g); e != INVALID; ++e) cap[e] = 17 * cap[e]; | 
|---|
| [1060] | 317 |   max_flow.init(flow); | 
|---|
 | 318 |  | 
|---|
 | 319 |   SF::startFirstPhase(max_flow);       // start first phase of the algorithm | 
|---|
| [389] | 320 |  | 
|---|
 | 321 |   CutMap min_cut1(g); | 
|---|
| [1060] | 322 |   max_flow.minCutMap(min_cut1); | 
|---|
 | 323 |   min_cut_value = cutValue(g, min_cut1, cap); | 
|---|
| [389] | 324 |  | 
|---|
| [1169] | 325 |   check(!tol.different(17 * expected, max_flow.flowValue()), | 
|---|
| [1168] | 326 |         "Incorrect max flow value."); | 
|---|
| [1169] | 327 |   check(!tol.different(17 * expected, min_cut_value), | 
|---|
| [1168] | 328 |         "Incorrect min cut value."); | 
|---|
| [389] | 329 |  | 
|---|
| [1060] | 330 |   SF::startSecondPhase(max_flow);       // start second phase of the algorithm | 
|---|
| [389] | 331 |  | 
|---|
| [1167] | 332 |   check(checkFlow(g, max_flow.flowMap(), cap, s, t, tol), | 
|---|
| [389] | 333 |         "The flow is not feasible."); | 
|---|
 | 334 |  | 
|---|
 | 335 |   CutMap min_cut2(g); | 
|---|
| [1060] | 336 |   max_flow.minCutMap(min_cut2); | 
|---|
 | 337 |   min_cut_value = cutValue(g, min_cut2, cap); | 
|---|
| [389] | 338 |  | 
|---|
| [1169] | 339 |   check(!tol.different(17 * expected, max_flow.flowValue()), | 
|---|
| [1168] | 340 |         "Incorrect max flow value."); | 
|---|
| [1169] | 341 |   check(!tol.different(17 * expected, min_cut_value), | 
|---|
| [1168] | 342 |         "Incorrect min cut value."); | 
|---|
| [389] | 343 |  | 
|---|
| [1060] | 344 |   max_flow.flowMap(flow); | 
|---|
| [389] | 345 |  | 
|---|
| [1060] | 346 |   NodeIt tmp1(g, s); | 
|---|
| [389] | 347 |   ++tmp1; | 
|---|
| [1060] | 348 |   if (tmp1 != INVALID) s = tmp1; | 
|---|
| [389] | 349 |  | 
|---|
| [1060] | 350 |   NodeIt tmp2(g, t); | 
|---|
| [389] | 351 |   ++tmp2; | 
|---|
| [1060] | 352 |   if (tmp2 != INVALID) t = tmp2; | 
|---|
| [389] | 353 |  | 
|---|
| [1060] | 354 |   max_flow.source(s); | 
|---|
 | 355 |   max_flow.target(t); | 
|---|
| [389] | 356 |  | 
|---|
| [1060] | 357 |   max_flow.run(); | 
|---|
| [389] | 358 |  | 
|---|
 | 359 |   CutMap min_cut3(g); | 
|---|
| [1060] | 360 |   max_flow.minCutMap(min_cut3); | 
|---|
| [1166] | 361 |   min_cut_value = cutValue(g, min_cut3, cap); | 
|---|
| [389] | 362 |  | 
|---|
| [1167] | 363 |   check(!tol.different(max_flow.flowValue(), min_cut_value), | 
|---|
| [1060] | 364 |         "The max flow value or the min cut value is wrong."); | 
|---|
 | 365 | } | 
|---|
| [389] | 366 |  | 
|---|
| [1060] | 367 | // Struct for calling start functions of a general max flow algorithm | 
|---|
 | 368 | template <typename MF> | 
|---|
 | 369 | struct GeneralStartFunctions { | 
|---|
 | 370 |  | 
|---|
 | 371 |   static void startFirstPhase(MF& mf) { | 
|---|
 | 372 |     mf.start(); | 
|---|
 | 373 |   } | 
|---|
 | 374 |  | 
|---|
 | 375 |   static void startSecondPhase(MF& mf) { | 
|---|
| [1087] | 376 |     ::lemon::ignore_unused_variable_warning(mf); | 
|---|
| [1060] | 377 |   } | 
|---|
 | 378 |  | 
|---|
 | 379 | }; | 
|---|
 | 380 |  | 
|---|
 | 381 | // Struct for calling start functions of Preflow | 
|---|
 | 382 | template <typename MF> | 
|---|
 | 383 | struct PreflowStartFunctions { | 
|---|
 | 384 |  | 
|---|
 | 385 |   static void startFirstPhase(MF& mf) { | 
|---|
 | 386 |     mf.startFirstPhase(); | 
|---|
 | 387 |   } | 
|---|
 | 388 |  | 
|---|
 | 389 |   static void startSecondPhase(MF& mf) { | 
|---|
 | 390 |     mf.startSecondPhase(); | 
|---|
 | 391 |   } | 
|---|
 | 392 |  | 
|---|
 | 393 | }; | 
|---|
 | 394 |  | 
|---|
 | 395 | int main() { | 
|---|
 | 396 |  | 
|---|
 | 397 |   typedef concepts::Digraph GR; | 
|---|
 | 398 |   typedef concepts::ReadMap<GR::Arc, int> CM1; | 
|---|
 | 399 |   typedef concepts::ReadMap<GR::Arc, double> CM2; | 
|---|
 | 400 |  | 
|---|
 | 401 |   // Check the interface of Preflow | 
|---|
 | 402 |   checkConcept< MaxFlowClassConcept<GR, CM1>, | 
|---|
 | 403 |                 Preflow<GR, CM1> >(); | 
|---|
 | 404 |   checkConcept< MaxFlowClassConcept<GR, CM2>, | 
|---|
 | 405 |                 Preflow<GR, CM2> >(); | 
|---|
 | 406 |  | 
|---|
 | 407 |   // Check the interface of EdmondsKarp | 
|---|
 | 408 |   checkConcept< MaxFlowClassConcept<GR, CM1>, | 
|---|
 | 409 |                 EdmondsKarp<GR, CM1> >(); | 
|---|
 | 410 |   checkConcept< MaxFlowClassConcept<GR, CM2>, | 
|---|
 | 411 |                 EdmondsKarp<GR, CM2> >(); | 
|---|
 | 412 |  | 
|---|
 | 413 |   // Check Preflow | 
|---|
 | 414 |   typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<int> > PType1; | 
|---|
 | 415 |   typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<float> > PType2; | 
|---|
| [1168] | 416 |   typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<double> > PType3; | 
|---|
| [1169] | 417 |  | 
|---|
| [1168] | 418 |   checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >(test_lgf, 13); | 
|---|
 | 419 |   checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >(test_lgf, 13); | 
|---|
 | 420 |   checkMaxFlowAlg<PType3, PreflowStartFunctions<PType3> >(test_lgf, 13); | 
|---|
| [1166] | 421 |  | 
|---|
| [1178] | 422 |   checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >(test_lgf_float, 0.3f); | 
|---|
| [1169] | 423 |   checkMaxFlowAlg<PType3, PreflowStartFunctions<PType3> >(test_lgf_float, 0.3); | 
|---|
 | 424 |  | 
|---|
| [1166] | 425 |   checkInitPreflow(); | 
|---|
| [1092] | 426 |  | 
|---|
| [1060] | 427 |   // Check EdmondsKarp | 
|---|
 | 428 |   typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<int> > EKType1; | 
|---|
 | 429 |   typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<float> > EKType2; | 
|---|
| [1168] | 430 |   typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<double> > EKType3; | 
|---|
| [1169] | 431 |  | 
|---|
| [1168] | 432 |   checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >(test_lgf, 13); | 
|---|
 | 433 |   checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >(test_lgf, 13); | 
|---|
 | 434 |   checkMaxFlowAlg<EKType3, GeneralStartFunctions<EKType3> >(test_lgf, 13); | 
|---|
| [389] | 435 |  | 
|---|
| [1178] | 436 |   checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >(test_lgf_float, 0.3f); | 
|---|
| [1169] | 437 |   checkMaxFlowAlg<EKType3, GeneralStartFunctions<EKType3> >(test_lgf_float, 0.3); | 
|---|
 | 438 |  | 
|---|
| [389] | 439 |   return 0; | 
|---|
 | 440 | } | 
|---|