Ticket #177: 177-patches-87df475c2753--2ecc1e07d4ff.patch
File 177-patches-87df475c2753--2ecc1e07d4ff.patch, 37.6 KB (added by , 12 years ago) |
---|
-
lemon/edmonds_karp.h
# HG changeset patch # User Peter Kovacs <kpeter@inf.elte.hu> # Date 1362071873 -3600 # Node ID 87df475c275311687b9a1dccb0c6fb993d81cd2f # Parent be2b4a8d4548920c639259882b72429302c514ab Improve and fix API doc of EdmondsKarp according to Preflow (#177) diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
a b 45 45 /// It must meet the \ref concepts::ReadMap "ReadMap" concept. 46 46 typedef CAP CapacityMap; 47 47 48 /// \brief The type of the length of the arcs.48 /// \brief The type of the flow values. 49 49 typedef typename CapacityMap::Value Value; 50 50 51 /// \brief The map typethat stores the flow values.51 /// \brief The type of the map that stores the flow values. 52 52 /// 53 /// The map type that stores the flow values.53 /// The type of the map that stores the flow values. 54 54 /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 55 #ifdef DOXYGEN 56 typedef GR::ArcMap<Value> FlowMap; 57 #else 55 58 typedef typename Digraph::template ArcMap<Value> FlowMap; 59 #endif 56 60 57 61 /// \brief Instantiates a FlowMap. 58 62 /// 59 63 /// This function instantiates a \ref FlowMap. 60 /// \param digraph The digraph, to which we would like to define the flow map. 64 /// \param digraph The digraph for which we would like to define 65 /// the flow map. 61 66 static FlowMap* createFlowMap(const Digraph& digraph) { 62 67 return new FlowMap(digraph); 63 68 } … … 74 79 /// \brief Edmonds-Karp algorithms class. 75 80 /// 76 81 /// This class provides an implementation of the \e Edmonds-Karp \e 77 /// algorithm producing a flow of maximum value in directed 78 /// digraphs. The Edmonds-Karp algorithm is slower than the Preflow 79 /// algorithm but it has an advantage of the step-by-step execution 82 /// algorithm producing a \ref max_flow "flow of maximum value" in a 83 /// digraph \ref clrs01algorithms, \ref amo93networkflows, 84 /// \ref edmondskarp72theoretical. 85 /// The Edmonds-Karp algorithm is slower than the Preflow 86 /// algorithm, but it has an advantage of the step-by-step execution 80 87 /// control with feasible flow solutions. The \e source node, the \e 81 88 /// target node, the \e capacity of the arcs and the \e starting \e 82 89 /// flow value of the arcs should be passed to the algorithm 83 90 /// through the constructor. 84 91 /// 85 92 /// The time complexity of the algorithm is \f$ O(nm^2) \f$ in 86 /// worst case. Always try the preflow algorithm instead of this if93 /// worst case. Always try the Preflow algorithm instead of this if 87 94 /// you just want to compute the optimal flow. 88 95 /// 89 /// \param GR The digraph type the algorithm runs on. 90 /// \param CAP The capacity map type. 91 /// \param TR Traits class to set various data types used by 92 /// the algorithm. The default traits class is \ref 93 /// EdmondsKarpDefaultTraits. See \ref EdmondsKarpDefaultTraits for the 94 /// documentation of a Edmonds-Karp traits class. 96 /// \tparam GR The type of the digraph the algorithm runs on. 97 /// \tparam CAP The type of the capacity map. The default map 98 /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>". 99 /// \tparam TR The traits class that defines various types used by the 100 /// algorithm. By default, it is \ref EdmondsKarpDefaultTraits 101 /// "EdmondsKarpDefaultTraits<GR, CAP>". 102 /// In most cases, this parameter should not be set directly, 103 /// consider to use the named template parameters instead. 95 104 96 105 #ifdef DOXYGEN 97 106 template <typename GR, typename CAP, typename TR> … … 103 112 class EdmondsKarp { 104 113 public: 105 114 115 /// The \ref EdmondsKarpDefaultTraits "traits class" of the algorithm. 106 116 typedef TR Traits; 117 /// The type of the digraph the algorithm runs on. 107 118 typedef typename Traits::Digraph Digraph; 119 /// The type of the capacity map. 108 120 typedef typename Traits::CapacityMap CapacityMap; 121 /// The type of the flow values. 109 122 typedef typename Traits::Value Value; 110 123 124 /// The type of the flow map. 111 125 typedef typename Traits::FlowMap FlowMap; 126 /// The type of the tolerance. 112 127 typedef typename Traits::Tolerance Tolerance; 113 128 114 129 private: … … 160 175 struct DefFlowMapTraits : public Traits { 161 176 typedef T FlowMap; 162 177 static FlowMap *createFlowMap(const Digraph&) { 163 LEMON_ASSERT(false, "Uninitialized parameter.");178 LEMON_ASSERT(false, "FlowMap is not initialized"); 164 179 return 0; 165 180 } 166 181 }; … … 173 188 template <typename T> 174 189 struct DefFlowMap 175 190 : public EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> > { 176 typedef EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> > 191 typedef EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> > 177 192 Create; 178 193 }; 179 194 180 181 195 /// @} 182 196 183 197 protected: … … 198 212 : _graph(digraph), _capacity(&capacity), _source(source), _target(target), 199 213 _flow(0), _local_flow(false), _pred(0), _tolerance(), _flow_value() 200 214 { 201 LEMON_ASSERT(_source != _target,"Flow source and target are the same nodes."); 215 LEMON_ASSERT(_source != _target, 216 "Flow source and target are the same nodes."); 202 217 } 203 218 204 219 /// \brief Destructor. … … 211 226 /// \brief Sets the capacity map. 212 227 /// 213 228 /// Sets the capacity map. 214 /// \return \c (*this)229 /// \return <tt>(*this)</tt> 215 230 EdmondsKarp& capacityMap(const CapacityMap& map) { 216 231 _capacity = ↦ 217 232 return *this; … … 220 235 /// \brief Sets the flow map. 221 236 /// 222 237 /// Sets the flow map. 223 /// \return \c (*this) 238 /// If you don't use this function before calling \ref run() or 239 /// \ref init(), an instance will be allocated automatically. 240 /// The destructor deallocates this automatically allocated map, 241 /// of course. 242 /// \return <tt>(*this)</tt> 224 243 EdmondsKarp& flowMap(FlowMap& map) { 225 244 if (_local_flow) { 226 245 delete _flow; … … 230 249 return *this; 231 250 } 232 251 233 /// \brief Returns the flow map.234 ///235 /// \return The flow map.236 const FlowMap& flowMap() const {237 return *_flow;238 }239 240 252 /// \brief Sets the source node. 241 253 /// 242 254 /// Sets the source node. 243 /// \return \c (*this)255 /// \return <tt>(*this)</tt> 244 256 EdmondsKarp& source(const Node& node) { 245 257 _source = node; 246 258 return *this; … … 249 261 /// \brief Sets the target node. 250 262 /// 251 263 /// Sets the target node. 252 /// \return \c (*this)264 /// \return <tt>(*this)</tt> 253 265 EdmondsKarp& target(const Node& node) { 254 266 _target = node; 255 267 return *this; … … 258 270 /// \brief Sets the tolerance used by algorithm. 259 271 /// 260 272 /// Sets the tolerance used by algorithm. 273 /// \return <tt>(*this)</tt> 261 274 EdmondsKarp& tolerance(const Tolerance& tolerance) { 262 275 _tolerance = tolerance; 263 276 return *this; 264 277 } 265 278 266 /// \brief Returns the tolerance used by algorithm.279 /// \brief Returns a const reference to the tolerance. 267 280 /// 268 /// Returns the tolerance used by algorithm. 281 /// Returns a const reference to the tolerance object used by 282 /// the algorithm. 269 283 const Tolerance& tolerance() const { 270 284 return _tolerance; 271 285 } 272 286 273 287 /// \name Execution control 274 /// The simplest way to execute the 275 /// algorithm is to use the \c run() member functions. 276 /// \n 277 /// If you need more control on initial solution or 278 /// execution then you have to call one \ref init() function and then 279 /// the start() or multiple times the \c augment() member function. 288 /// The simplest way to execute the algorithm is to use \ref run().\n 289 /// If you need better control on the initial solution or the execution, 290 /// you have to call one of the \ref init() functions first, then 291 /// \ref start() or multiple times the \ref augment() function. 280 292 281 293 ///@{ 282 294 283 /// \brief Initializes the algorithm 284 /// 285 /// Sets the flow to empty flow. 295 /// \brief Initializes the algorithm. 296 /// 297 /// Initializes the internal data structures and sets the initial 298 /// flow to zero on each arc. 286 299 void init() { 287 300 createStructures(); 288 301 for (ArcIt it(_graph); it != INVALID; ++it) { … … 291 304 _flow_value = 0; 292 305 } 293 306 294 /// \brief Initializes the algorithm 295 /// 296 /// Initializes the flow to the \c flowMap. The \c flowMap should 297 /// contain a feasible flow, ie. in each node excluding the source 298 /// and the target the incoming flow should be equal to the 307 /// \brief Initializes the algorithm using the given flow map. 308 /// 309 /// Initializes the internal data structures and sets the initial 310 /// flow to the given \c flowMap. The \c flowMap should 311 /// contain a feasible flow, i.e. at each node excluding the source 312 /// and the target, the incoming flow should be equal to the 299 313 /// outgoing flow. 300 314 template <typename FlowMap> 301 315 void flowInit(const FlowMap& flowMap) { … … 312 326 } 313 327 } 314 328 315 /// \brief Initializes the algorithm 316 /// 317 /// Initializes the flow to the \c flowMap. The \c flowMap should 318 /// contain a feasible flow, ie. in each node excluding the source 319 /// and the target the incoming flow should be equal to the 320 /// outgoing flow. 321 /// \return %False when the given flowMap does not contain 329 /// \brief Initializes the algorithm using the given flow map. 330 /// 331 /// Initializes the internal data structures and sets the initial 332 /// flow to the given \c flowMap. The \c flowMap should 333 /// contain a feasible flow, i.e. at each node excluding the source 334 /// and the target, the incoming flow should be equal to the 335 /// outgoing flow. 336 /// \return \c false when the given \c flowMap does not contain a 322 337 /// feasible flow. 323 338 template <typename FlowMap> 324 339 bool checkedFlowInit(const FlowMap& flowMap) { … … 354 369 return true; 355 370 } 356 371 357 /// \brief Augment the solution on an arcshortest path.372 /// \brief Augments the solution along a shortest path. 358 373 /// 359 /// Augment the solution on an arc shortest path. It searches an360 /// arcshortest path between the source and the target361 /// in the residual digraph by the bfs algoritm.374 /// Augments the solution along a shortest path. This function searches a 375 /// shortest path between the source and the target 376 /// in the residual digraph by the Bfs algoritm. 362 377 /// Then it increases the flow on this path with the minimal residual 363 /// capacity on the path. If there is no such path it gives back378 /// capacity on the path. If there is no such path, it gives back 364 379 /// false. 365 /// \return %False when the augmenting didn't success sothe380 /// \return \c false when the augmenting did not success, i.e. the 366 381 /// current flow is a feasible and optimal solution. 367 382 bool augment() { 368 383 for (NodeIt n(_graph); n != INVALID; ++n) { … … 439 454 440 455 /// \brief Executes the algorithm 441 456 /// 442 /// It runs augmenting phases until the optimal solution is reached. 457 /// Executes the algorithm by performing augmenting phases until the 458 /// optimal solution is reached. 459 /// \pre One of the \ref init() functions must be called before 460 /// using this function. 443 461 void start() { 444 462 while (augment()) {} 445 463 } 446 464 447 465 /// \brief Runs the algorithm. 448 466 /// 449 /// It is just a shorthand for:450 /// 467 /// Runs the Edmonds-Karp algorithm. 468 /// \note ek.run() is just a shortcut of the following code. 451 469 ///\code 452 470 /// ek.init(); 453 471 /// ek.start(); … … 462 480 /// \name Query Functions 463 481 /// The result of the Edmonds-Karp algorithm can be obtained using these 464 482 /// functions.\n 465 /// Before the use of these functions, 466 /// either run() or start() must be called. 483 /// Either \ref run() or \ref start() should be called before using them. 467 484 468 485 ///@{ 469 486 470 487 /// \brief Returns the value of the maximum flow. 471 488 /// 472 /// Returns the value of the maximum flow by returning the excess 473 /// of the target node \c t. 474 489 /// Returns the value of the maximum flow found by the algorithm. 490 /// 491 /// \pre Either \ref run() or \ref init() must be called before 492 /// using this function. 475 493 Value flowValue() const { 476 494 return _flow_value; 477 495 } 478 496 479 480 /// \brief Returns the flow on the arc. 497 /// \brief Returns the flow value on the given arc. 481 498 /// 482 /// Sets the \c flowMap to the flow on the arcs. 499 /// Returns the flow value on the given arc. 500 /// 501 /// \pre Either \ref run() or \ref init() must be called before 502 /// using this function. 483 503 Value flow(const Arc& arc) const { 484 504 return (*_flow)[arc]; 485 505 } 486 506 487 /// \brief Returns true when the node is on the source side of minimum cut.507 /// \brief Returns a const reference to the flow map. 488 508 /// 509 /// Returns a const reference to the arc map storing the found flow. 510 /// 511 /// \pre Either \ref run() or \ref init() must be called before 512 /// using this function. 513 const FlowMap& flowMap() const { 514 return *_flow; 515 } 489 516 490 /// Returns true when the node is on the source side of minimum 491 /// cut. 492 517 /// \brief Returns \c true when the node is on the source side of the 518 /// minimum cut. 519 /// 520 /// Returns true when the node is on the source side of the found 521 /// minimum cut. 522 /// 523 /// \pre Either \ref run() or \ref init() must be called before 524 /// using this function. 493 525 bool minCut(const Node& node) const { 494 526 return ((*_pred)[node] != INVALID) or node == _source; 495 527 } 496 528 497 /// \brief Returnsa minimum value cut.529 /// \brief Gives back a minimum value cut. 498 530 /// 499 /// Sets \c cutMap to the characteristic vector of a minimum value cut. 500 531 /// Sets \c cutMap to the characteristic vector of a minimum value 532 /// cut. \c cutMap should be a \ref concepts::WriteMap "writable" 533 /// node map with \c bool (or convertible) value type. 534 /// 535 /// \note This function calls \ref minCut() for each node, so it runs in 536 /// O(n) time. 537 /// 538 /// \pre Either \ref run() or \ref init() must be called before 539 /// using this function. 501 540 template <typename CutMap> 502 541 void minCutMap(CutMap& cutMap) const { 503 542 for (NodeIt n(_graph); n != INVALID; ++n) { -
lemon/edmonds_karp.h
# HG changeset patch # User Peter Kovacs <kpeter@inf.elte.hu> # Date 1362071156 -3600 # Node ID 0ad9454fd0b6f0307d01e0baf23ac9642983e6a1 # Parent 87df475c275311687b9a1dccb0c6fb993d81cd2f Rename DefFlowMap named parameter to SetFlowMap (#177) in EdmondsKarp according to Preflow diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
a b 172 172 ///@{ 173 173 174 174 template <typename T> 175 struct DefFlowMapTraits : public Traits {175 struct SetFlowMapTraits : public Traits { 176 176 typedef T FlowMap; 177 177 static FlowMap *createFlowMap(const Digraph&) { 178 178 LEMON_ASSERT(false, "FlowMap is not initialized"); … … 186 186 /// \ref named-templ-param "Named parameter" for setting FlowMap 187 187 /// type 188 188 template <typename T> 189 struct DefFlowMap 190 : public EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> > { 191 typedef EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> > 192 Create; 189 struct SetFlowMap 190 : public EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > { 191 typedef EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > Create; 193 192 }; 194 193 195 194 /// @} -
test/edmonds_karp_test.cc
diff --git a/test/edmonds_karp_test.cc b/test/edmonds_karp_test.cc
a b 83 83 bool b; 84 84 85 85 typedef EdmondsKarp<Digraph, CapMap> 86 :: DefFlowMap<FlowMap>86 ::SetFlowMap<FlowMap> 87 87 ::Create EKType; 88 88 EKType ek_test(g, cap, n, n); 89 89 const EKType& const_ek_test = ek_test; -
lemon/edmonds_karp.h
# HG changeset patch # User Peter Kovacs <kpeter@inf.elte.hu> # Date 1362071628 -3600 # Node ID d1c4ed808574081acf145cb252f5ad5cca6ba772 # Parent 0ad9454fd0b6f0307d01e0baf23ac9642983e6a1 Rename flow init functions according to Preflow (#177) diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
a b 311 311 /// and the target, the incoming flow should be equal to the 312 312 /// outgoing flow. 313 313 template <typename FlowMap> 314 void flowInit(const FlowMap& flowMap) {314 void init(const FlowMap& flowMap) { 315 315 createStructures(); 316 316 for (ArcIt e(_graph); e != INVALID; ++e) { 317 317 _flow->set(e, flowMap[e]); … … 335 335 /// \return \c false when the given \c flowMap does not contain a 336 336 /// feasible flow. 337 337 template <typename FlowMap> 338 bool checked FlowInit(const FlowMap& flowMap) {338 bool checkedInit(const FlowMap& flowMap) { 339 339 createStructures(); 340 340 for (ArcIt e(_graph); e != INVALID; ++e) { 341 341 _flow->set(e, flowMap[e]); -
test/edmonds_karp_test.cc
diff --git a/test/edmonds_karp_test.cc b/test/edmonds_karp_test.cc
a b 186 186 int flow_value=ek_test.flowValue(); 187 187 188 188 for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e]; 189 ek_test. flowInit(flow);189 ek_test.init(flow); 190 190 ek_test.start(); 191 191 192 192 CutMap min_cut1(g); -
lemon/edmonds_karp.h
# HG changeset patch # User Peter Kovacs <kpeter@inf.elte.hu> # Date 1362091475 -3600 # Node ID 67ffe67e28de610b4114d0669f538eed1d435f97 # Parent d1c4ed808574081acf145cb252f5ad5cca6ba772 Merge test files of Preflow and EdmondsKarp (#177) diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
a b 167 167 168 168 public: 169 169 170 typedef EdmondsKarp Create; 171 170 172 ///\name Named template parameters 171 173 172 174 ///@{ -
test/CMakeLists.txt
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
a b 19 19 dijkstra_test 20 20 dim_test 21 21 edge_set_test 22 edmonds_karp_test23 22 error_test 24 23 euler_test 25 24 fractional_matching_test … … 34 33 matching_test 35 34 max_cardinality_search_test 36 35 max_clique_test 36 max_flow_test 37 37 min_cost_arborescence_test 38 38 min_cost_flow_test 39 39 min_mean_cycle_test 40 40 nagamochi_ibaraki_test 41 41 path_test 42 42 planarity_test 43 preflow_test44 43 radix_sort_test 45 44 random_test 46 45 suurballe_test -
test/Makefile.am
diff --git a/test/Makefile.am b/test/Makefile.am
a b 21 21 test/dijkstra_test \ 22 22 test/dim_test \ 23 23 test/edge_set_test \ 24 test/edmonds_karp_test \25 24 test/error_test \ 26 25 test/euler_test \ 27 26 test/fractional_matching_test \ … … 36 35 test/matching_test \ 37 36 test/max_cardinality_search_test \ 38 37 test/max_clique_test \ 38 test/max_flow_test \ 39 39 test/min_cost_arborescence_test \ 40 40 test/min_cost_flow_test \ 41 41 test/min_mean_cycle_test \ 42 42 test/nagamochi_ibaraki_test \ 43 43 test/path_test \ 44 44 test/planarity_test \ 45 test/preflow_test \46 45 test/radix_sort_test \ 47 46 test/random_test \ 48 47 test/suurballe_test \ … … 74 73 test_dijkstra_test_SOURCES = test/dijkstra_test.cc 75 74 test_dim_test_SOURCES = test/dim_test.cc 76 75 test_edge_set_test_SOURCES = test/edge_set_test.cc 77 test_edmonds_karp_test_SOURCES = test/edmonds_karp_test.cc78 76 test_error_test_SOURCES = test/error_test.cc 79 77 test_euler_test_SOURCES = test/euler_test.cc 80 78 test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc … … 91 89 test_matching_test_SOURCES = test/matching_test.cc 92 90 test_max_cardinality_search_test_SOURCES = test/max_cardinality_search_test.cc 93 91 test_max_clique_test_SOURCES = test/max_clique_test.cc 92 test_max_flow_test_SOURCES = test/max_flow_test.cc 94 93 test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc 95 94 test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc 96 95 test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc 97 96 test_nagamochi_ibaraki_test_SOURCES = test/nagamochi_ibaraki_test.cc 98 97 test_path_test_SOURCES = test/path_test.cc 99 98 test_planarity_test_SOURCES = test/planarity_test.cc 100 test_preflow_test_SOURCES = test/preflow_test.cc101 99 test_radix_sort_test_SOURCES = test/radix_sort_test.cc 102 100 test_suurballe_test_SOURCES = test/suurballe_test.cc 103 101 test_random_test_SOURCES = test/random_test.cc -
deleted file test/edmonds_karp_test.cc
diff --git a/test/edmonds_karp_test.cc b/test/edmonds_karp_test.cc deleted file mode 100644
+ - 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-20106 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport7 * (Egervary Research Group on Combinatorial Optimization, EGRES).8 *9 * Permission to use, modify and distribute this software is granted10 * provided that this copyright notice appears in all copies. For11 * 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 any15 * purpose.16 *17 */18 19 #include<iostream>20 21 #include "test_tools.h"22 #include<lemon/smart_graph.h>23 #include<lemon/edmonds_karp.h>24 #include <lemon/concepts/digraph.h>25 #include <lemon/concepts/maps.h>26 #include <lemon/lgf_reader.h>27 28 using namespace lemon;29 30 char test_lgf[] =31 "@nodes\n"32 "label\n"33 "0\n"34 "1\n"35 "2\n"36 "3\n"37 "4\n"38 "5\n"39 "6\n"40 "7\n"41 "8\n"42 "9\n"43 "@arcs\n"44 " label capacity\n"45 "0 1 0 20\n"46 "0 2 1 0\n"47 "1 1 2 3\n"48 "1 2 3 8\n"49 "1 3 4 8\n"50 "2 5 5 5\n"51 "3 2 6 5\n"52 "3 5 7 5\n"53 "3 6 8 5\n"54 "4 3 9 3\n"55 "5 7 10 3\n"56 "5 6 11 10\n"57 "5 8 12 10\n"58 "6 8 13 8\n"59 "8 9 14 20\n"60 "8 1 15 5\n"61 "9 5 16 5\n"62 "@attributes\n"63 "source 1\n"64 "target 8\n";65 66 void checkEdmondKarpCompile() {67 typedef int VType;68 typedef concepts::Digraph Digraph;69 70 typedef Digraph::Node Node;71 typedef Digraph::Arc Arc;72 typedef concepts::ReadMap<Arc,VType> CapMap;73 typedef concepts::ReadWriteMap<Arc,VType> FlowMap;74 typedef concepts::WriteMap<Node,bool> CutMap;75 76 Digraph g;77 Node n;78 Arc e;79 CapMap cap;80 FlowMap flow;81 CutMap cut;82 VType v;83 bool b;84 85 typedef EdmondsKarp<Digraph, CapMap>86 ::SetFlowMap<FlowMap>87 ::Create EKType;88 EKType ek_test(g, cap, n, n);89 const EKType& const_ek_test = ek_test;90 91 EKType::Tolerance tol = const_ek_test.tolerance();92 ek_test.tolerance(tol);93 94 ek_test95 .capacityMap(cap)96 .flowMap(flow)97 .source(n)98 .target(n);99 100 ek_test.init();101 ek_test.start();102 103 v = const_ek_test.flowValue();104 v = const_ek_test.flow(e);105 106 const FlowMap& fm = const_ek_test.flowMap();107 b = const_ek_test.minCut(n);108 const_ek_test.minCutMap(cut);109 110 ignore_unused_variable_warning(fm);111 }112 113 int cutValue (const SmartDigraph& g,114 const SmartDigraph::NodeMap<bool>& cut,115 const SmartDigraph::ArcMap<int>& cap) {116 117 int c=0;118 for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {119 if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];120 }121 return c;122 }123 124 bool checkFlow(const SmartDigraph& g,125 const SmartDigraph::ArcMap<int>& flow,126 const SmartDigraph::ArcMap<int>& cap,127 SmartDigraph::Node s, SmartDigraph::Node t) {128 129 for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {130 if (flow[e] < 0 || flow[e] > cap[e]) return false;131 }132 133 for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {134 if (n == s || n == t) continue;135 int sum = 0;136 for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {137 sum += flow[e];138 }139 for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {140 sum -= flow[e];141 }142 if (sum != 0) return false;143 }144 return true;145 }146 147 int main() {148 149 typedef SmartDigraph Digraph;150 151 typedef Digraph::Node Node;152 typedef Digraph::NodeIt NodeIt;153 typedef Digraph::ArcIt ArcIt;154 typedef Digraph::ArcMap<int> CapMap;155 typedef Digraph::ArcMap<int> FlowMap;156 typedef Digraph::NodeMap<bool> CutMap;157 158 typedef EdmondsKarp<Digraph, CapMap> EKType;159 160 Digraph g;161 Node s, t;162 CapMap cap(g);163 std::istringstream input(test_lgf);164 DigraphReader<Digraph>(g,input).165 arcMap("capacity", cap).166 node("source",s).167 node("target",t).168 run();169 170 EKType ek_test(g, cap, s, t);171 ek_test.run();172 173 check(checkFlow(g, ek_test.flowMap(), cap, s, t),174 "The flow is not feasible.");175 176 CutMap min_cut(g);177 ek_test.minCutMap(min_cut);178 int min_cut_value=cutValue(g,min_cut,cap);179 180 check(ek_test.flowValue() == min_cut_value,181 "The max flow value is not equal to the three min cut values.");182 183 FlowMap flow(g);184 for(ArcIt e(g); e!=INVALID; ++e) flow[e] = ek_test.flowMap()[e];185 186 int flow_value=ek_test.flowValue();187 188 for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];189 ek_test.init(flow);190 ek_test.start();191 192 CutMap min_cut1(g);193 ek_test.minCutMap(min_cut1);194 min_cut_value=cutValue(g,min_cut1,cap);195 196 check(ek_test.flowValue() == min_cut_value &&197 min_cut_value == 2*flow_value,198 "The max flow value or the min cut value is wrong.");199 200 check(checkFlow(g, ek_test.flowMap(), cap, s, t),201 "The flow is not feasible.");202 203 CutMap min_cut2(g);204 ek_test.minCutMap(min_cut2);205 min_cut_value=cutValue(g,min_cut2,cap);206 207 check(ek_test.flowValue() == min_cut_value &&208 min_cut_value == 2*flow_value,209 "The max flow value or the three min cut values were not doubled.");210 211 212 ek_test.flowMap(flow);213 214 NodeIt tmp1(g,s);215 ++tmp1;216 if ( tmp1 != INVALID ) s=tmp1;217 218 NodeIt tmp2(g,t);219 ++tmp2;220 if ( tmp2 != INVALID ) t=tmp2;221 222 ek_test.source(s);223 ek_test.target(t);224 225 ek_test.run();226 227 CutMap min_cut3(g);228 ek_test.minCutMap(min_cut3);229 min_cut_value=cutValue(g,min_cut3,cap);230 231 232 check(ek_test.flowValue() == min_cut_value,233 "The max flow value or the three min cut values are incorrect.");234 235 return 0;236 } -
.cc
diff --git a/test/preflow_test.cc b/test/max_flow_test.cc rename from test/preflow_test.cc rename to test/max_flow_test.cc
old new 21 21 #include "test_tools.h" 22 22 #include <lemon/smart_graph.h> 23 23 #include <lemon/preflow.h> 24 #include <lemon/edmonds_karp.h> 24 25 #include <lemon/concepts/digraph.h> 25 26 #include <lemon/concepts/maps.h> 26 27 #include <lemon/lgf_reader.h> … … 64 65 "source 1\n" 65 66 "target 8\n"; 66 67 68 69 // Checks the general interface of a max flow algorithm 70 template <typename GR, typename CAP> 71 struct MaxFlowClassConcept 72 { 73 74 template <typename MF> 75 struct Constraints { 76 77 typedef typename GR::Node Node; 78 typedef typename GR::Arc Arc; 79 typedef typename CAP::Value Value; 80 typedef concepts::ReadWriteMap<Arc, Value> FlowMap; 81 typedef concepts::WriteMap<Node, bool> CutMap; 82 83 GR g; 84 Node n; 85 Arc e; 86 CAP cap; 87 FlowMap flow; 88 CutMap cut; 89 Value v; 90 bool b; 91 92 void constraints() { 93 checkConcept<concepts::Digraph, GR>(); 94 95 const Constraints& me = *this; 96 97 typedef typename MF 98 ::template SetFlowMap<FlowMap> 99 ::Create MaxFlowType; 100 typedef typename MF::Create MaxFlowType2; 101 MaxFlowType max_flow(me.g, me.cap, me.n, me.n); 102 const MaxFlowType& const_max_flow = max_flow; 103 104 max_flow 105 .capacityMap(cap) 106 .flowMap(flow) 107 .source(n) 108 .target(n); 109 110 typename MaxFlowType::Tolerance tol = const_max_flow.tolerance(); 111 max_flow.tolerance(tol); 112 113 max_flow.init(); 114 max_flow.init(cap); 115 max_flow.run(); 116 117 v = const_max_flow.flowValue(); 118 v = const_max_flow.flow(e); 119 const FlowMap& fm = const_max_flow.flowMap(); 120 121 b = const_max_flow.minCut(n); 122 const_max_flow.minCutMap(cut); 123 124 ignore_unused_variable_warning(fm); 125 } 126 127 }; 128 129 }; 130 131 // Checks the specific parts of Preflow's interface 67 132 void checkPreflowCompile() 68 133 { 69 typedef int V Type;134 typedef int Value; 70 135 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 136 typedef concepts::ReadMap<Digraph::Arc, Value> CapMap; 78 137 typedef Elevator<Digraph, Digraph::Node> Elev; 79 138 typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev; 80 139 81 140 Digraph g; 82 Node n; 83 Arc e; 141 Digraph::Node n; 84 142 CapMap cap; 85 FlowMap flow;86 CutMap cut;87 VType v;88 bool b;89 143 90 144 typedef Preflow<Digraph, CapMap> 91 ::SetFlowMap<FlowMap> 92 ::SetElevator<Elev> 93 ::SetStandardElevator<LinkedElev> 94 ::Create PreflowType; 145 ::SetElevator<Elev> 146 ::SetStandardElevator<LinkedElev> 147 ::Create PreflowType; 95 148 PreflowType preflow_test(g, cap, n, n); 96 149 const PreflowType& const_preflow_test = preflow_test; 97 150 98 151 const PreflowType::Elevator& elev = const_preflow_test.elevator(); 99 152 preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev)); 100 PreflowType::Tolerance tol = const_preflow_test.tolerance();101 preflow_test.tolerance(tol);102 153 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); 154 bool b = preflow_test.init(cap); 111 155 preflow_test.startFirstPhase(); 112 156 preflow_test.startSecondPhase(); 113 preflow_test.run();114 157 preflow_test.runMinCut(); 115 158 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); 159 ignore_unused_variable_warning(b); 123 160 } 124 161 125 int cutValue (const SmartDigraph& g, 162 // Checks the specific parts of EdmondsKarp's interface 163 void checkEdmondsKarpCompile() 164 { 165 typedef int Value; 166 typedef concepts::Digraph Digraph; 167 typedef concepts::ReadMap<Digraph::Arc, Value> CapMap; 168 typedef Elevator<Digraph, Digraph::Node> Elev; 169 typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev; 170 171 Digraph g; 172 Digraph::Node n; 173 CapMap cap; 174 175 EdmondsKarp<Digraph, CapMap> ek_test(g, cap, n, n); 176 177 ek_test.init(cap); 178 bool b = ek_test.checkedInit(cap); 179 b = ek_test.augment(); 180 ek_test.start(); 181 182 ignore_unused_variable_warning(b); 183 } 184 185 186 template <typename T> 187 T cutValue (const SmartDigraph& g, 126 188 const SmartDigraph::NodeMap<bool>& cut, 127 const SmartDigraph::ArcMap< int>& cap) {189 const SmartDigraph::ArcMap<T>& cap) { 128 190 129 intc=0;191 T c=0; 130 192 for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) { 131 193 if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e]; 132 194 } 133 195 return c; 134 196 } 135 197 198 template <typename T> 136 199 bool checkFlow(const SmartDigraph& g, 137 const SmartDigraph::ArcMap< int>& flow,138 const SmartDigraph::ArcMap< int>& cap,200 const SmartDigraph::ArcMap<T>& flow, 201 const SmartDigraph::ArcMap<T>& cap, 139 202 SmartDigraph::Node s, SmartDigraph::Node t) { 140 203 141 204 for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) { … … 144 207 145 208 for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) { 146 209 if (n == s || n == t) continue; 147 intsum = 0;210 T sum = 0; 148 211 for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) { 149 212 sum += flow[e]; 150 213 } … … 156 219 return true; 157 220 } 158 221 159 int main() { 222 template <typename MF, typename SF> 223 void checkMaxFlowAlg() { 224 typedef SmartDigraph Digraph; 225 DIGRAPH_TYPEDEFS(Digraph); 160 226 161 typedef SmartDigraph Digraph; 162 163 typedef Digraph::Node Node; 164 typedef Digraph::NodeIt NodeIt; 165 typedef Digraph::ArcIt ArcIt; 166 typedef Digraph::ArcMap<int> CapMap; 167 typedef Digraph::ArcMap<int> FlowMap; 168 typedef Digraph::NodeMap<bool> CutMap; 169 170 typedef Preflow<Digraph, CapMap> PType; 227 typedef typename MF::Value Value; 228 typedef Digraph::ArcMap<Value> CapMap; 229 typedef CapMap FlowMap; 230 typedef BoolNodeMap CutMap; 171 231 172 232 Digraph g; 173 233 Node s, t; 174 234 CapMap cap(g); 175 235 std::istringstream input(test_lgf); 176 DigraphReader<Digraph>(g,input) .177 arcMap("capacity", cap).178 node("source",s).179 node("target",t).180 run();236 DigraphReader<Digraph>(g,input) 237 .arcMap("capacity", cap) 238 .node("source",s) 239 .node("target",t) 240 .run(); 181 241 182 PType preflow_test(g, cap, s, t);183 preflow_test.run();242 MF max_flow(g, cap, s, t); 243 max_flow.run(); 184 244 185 check(checkFlow(g, preflow_test.flowMap(), cap, s, t),245 check(checkFlow(g, max_flow.flowMap(), cap, s, t), 186 246 "The flow is not feasible."); 187 247 188 248 CutMap min_cut(g); 189 preflow_test.minCutMap(min_cut);190 int min_cut_value=cutValue(g,min_cut,cap);249 max_flow.minCutMap(min_cut); 250 Value min_cut_value = cutValue(g, min_cut, cap); 191 251 192 check( preflow_test.flowValue() == min_cut_value,193 "The max flow value is not equal to the three min cut values.");252 check(max_flow.flowValue() == min_cut_value, 253 "The max flow value is not equal to the min cut value."); 194 254 195 255 FlowMap flow(g); 196 for (ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];256 for (ArcIt e(g); e != INVALID; ++e) flow[e] = max_flow.flowMap()[e]; 197 257 198 int flow_value=preflow_test.flowValue();258 Value flow_value = max_flow.flowValue(); 199 259 200 for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e]; 201 preflow_test.init(flow); 202 preflow_test.startFirstPhase(); 260 for (ArcIt e(g); e != INVALID; ++e) cap[e] = 2 * cap[e]; 261 max_flow.init(flow); 262 263 SF::startFirstPhase(max_flow); // start first phase of the algorithm 203 264 204 265 CutMap min_cut1(g); 205 preflow_test.minCutMap(min_cut1);206 min_cut_value =cutValue(g,min_cut1,cap);266 max_flow.minCutMap(min_cut1); 267 min_cut_value = cutValue(g, min_cut1, cap); 207 268 208 check( preflow_test.flowValue() == min_cut_value &&209 min_cut_value == 2 *flow_value,269 check(max_flow.flowValue() == min_cut_value && 270 min_cut_value == 2 * flow_value, 210 271 "The max flow value or the min cut value is wrong."); 211 272 212 preflow_test.startSecondPhase();273 SF::startSecondPhase(max_flow); // start second phase of the algorithm 213 274 214 check(checkFlow(g, preflow_test.flowMap(), cap, s, t),275 check(checkFlow(g, max_flow.flowMap(), cap, s, t), 215 276 "The flow is not feasible."); 216 277 217 278 CutMap min_cut2(g); 218 preflow_test.minCutMap(min_cut2);219 min_cut_value =cutValue(g,min_cut2,cap);279 max_flow.minCutMap(min_cut2); 280 min_cut_value = cutValue(g, min_cut2, cap); 220 281 221 check( preflow_test.flowValue() == min_cut_value &&222 min_cut_value == 2 *flow_value,223 "The max flow value or the three min cut values werenot doubled");282 check(max_flow.flowValue() == min_cut_value && 283 min_cut_value == 2 * flow_value, 284 "The max flow value or the min cut value was not doubled"); 224 285 225 286 226 preflow_test.flowMap(flow);287 max_flow.flowMap(flow); 227 288 228 NodeIt tmp1(g, s);289 NodeIt tmp1(g, s); 229 290 ++tmp1; 230 if ( tmp1 != INVALID ) s=tmp1;291 if (tmp1 != INVALID) s = tmp1; 231 292 232 NodeIt tmp2(g, t);293 NodeIt tmp2(g, t); 233 294 ++tmp2; 234 if ( tmp2 != INVALID ) t=tmp2;295 if (tmp2 != INVALID) t = tmp2; 235 296 236 preflow_test.source(s);237 preflow_test.target(t);297 max_flow.source(s); 298 max_flow.target(t); 238 299 239 preflow_test.run();300 max_flow.run(); 240 301 241 302 CutMap min_cut3(g); 242 preflow_test.minCutMap(min_cut3);243 min_cut_value=cutValue(g, min_cut3,cap);303 max_flow.minCutMap(min_cut3); 304 min_cut_value=cutValue(g, min_cut3, cap); 244 305 306 check(max_flow.flowValue() == min_cut_value, 307 "The max flow value or the min cut value is wrong."); 308 } 245 309 246 check(preflow_test.flowValue() == min_cut_value, 247 "The max flow value or the three min cut values are incorrect."); 310 // Struct for calling start functions of a general max flow algorithm 311 template <typename MF> 312 struct GeneralStartFunctions { 313 314 static void startFirstPhase(MF& mf) { 315 mf.start(); 316 } 317 318 static void startSecondPhase(MF& mf) { 319 ignore_unused_variable_warning(mf); 320 } 321 322 }; 323 324 // Struct for calling start functions of Preflow 325 template <typename MF> 326 struct PreflowStartFunctions { 327 328 static void startFirstPhase(MF& mf) { 329 mf.startFirstPhase(); 330 } 331 332 static void startSecondPhase(MF& mf) { 333 mf.startSecondPhase(); 334 } 335 336 }; 337 338 int main() { 339 340 typedef concepts::Digraph GR; 341 typedef concepts::ReadMap<GR::Arc, int> CM1; 342 typedef concepts::ReadMap<GR::Arc, double> CM2; 343 344 // Check the interface of Preflow 345 checkConcept< MaxFlowClassConcept<GR, CM1>, 346 Preflow<GR, CM1> >(); 347 checkConcept< MaxFlowClassConcept<GR, CM2>, 348 Preflow<GR, CM2> >(); 349 350 // Check the interface of EdmondsKarp 351 checkConcept< MaxFlowClassConcept<GR, CM1>, 352 EdmondsKarp<GR, CM1> >(); 353 checkConcept< MaxFlowClassConcept<GR, CM2>, 354 EdmondsKarp<GR, CM2> >(); 355 356 // Check Preflow 357 typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<int> > PType1; 358 typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<float> > PType2; 359 checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >(); 360 checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >(); 361 362 // Check EdmondsKarp 363 typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<int> > EKType1; 364 typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<float> > EKType2; 365 checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >(); 366 checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >(); 248 367 249 368 return 0; 250 369 } -
lemon/edmonds_karp.h
# HG changeset patch # User Peter Kovacs <kpeter@inf.elte.hu> # Date 1362091539 -3600 # Node ID 2ecc1e07d4ff28b7e344dc04cd4595b9c8558afb # Parent 67ffe67e28de610b4114d0669f538eed1d435f97 Avoid usage of alternative operator (#177) diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
a b 524 524 /// \pre Either \ref run() or \ref init() must be called before 525 525 /// using this function. 526 526 bool minCut(const Node& node) const { 527 return ((*_pred)[node] != INVALID) ornode == _source;527 return ((*_pred)[node] != INVALID) || node == _source; 528 528 } 529 529 530 530 /// \brief Gives back a minimum value cut.