Changeset 1270:dceba191c00d in lemon for lemon/edmonds_karp.h
- Timestamp:
- 08/09/13 11:28:17 (11 years ago)
- Branch:
- default
- Children:
- 1271:fb1c7da561ce, 1381:e0ccc1f0268f
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/edmonds_karp.h
r1250 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-201 05 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 37 37 struct EdmondsKarpDefaultTraits { 38 38 39 /// \brief The digraph type the algorithm runs on. 39 /// \brief The digraph type the algorithm runs on. 40 40 typedef GR Digraph; 41 41 … … 61 61 /// \brief Instantiates a FlowMap. 62 62 /// 63 /// This function instantiates a \ref FlowMap. 63 /// This function instantiates a \ref FlowMap. 64 64 /// \param digraph The digraph for which we would like to define 65 65 /// the flow map. … … 96 96 /// \tparam GR The type of the digraph the algorithm runs on. 97 97 /// \tparam CAP The type of the capacity map. The default map 98 /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>". 98 /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>". 99 99 /// \tparam TR The traits class that defines various types used by the 100 100 /// algorithm. By default, it is \ref EdmondsKarpDefaultTraits … … 105 105 #ifdef DOXYGEN 106 106 template <typename GR, typename CAP, typename TR> 107 #else 107 #else 108 108 template <typename GR, 109 109 typename CAP = typename GR::template ArcMap<int>, 110 110 typename TR = EdmondsKarpDefaultTraits<GR, CAP> > 111 111 #endif … … 121 121 typedef typename Traits::CapacityMap CapacityMap; 122 122 /// The type of the flow values. 123 typedef typename Traits::Value Value; 123 typedef typename Traits::Value Value; 124 124 125 125 /// The type of the flow map. … … 132 132 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); 133 133 typedef typename Digraph::template NodeMap<Arc> PredMap; 134 134 135 135 const Digraph& _graph; 136 136 const CapacityMap* _capacity; … … 143 143 PredMap* _pred; 144 144 std::vector<Node> _queue; 145 145 146 146 Tolerance _tolerance; 147 147 Value _flow_value; … … 149 149 void createStructures() { 150 150 if (!_flow) { 151 152 151 _flow = Traits::createFlowMap(_graph); 152 _local_flow = true; 153 153 } 154 154 if (!_pred) { 155 155 _pred = new PredMap(_graph); 156 156 } 157 157 _queue.resize(countNodes(_graph)); … … 160 160 void destroyStructures() { 161 161 if (_local_flow) { 162 162 delete _flow; 163 163 } 164 164 if (_pred) { 165 166 } 167 } 168 165 delete _pred; 166 } 167 } 168 169 169 public: 170 170 … … 179 179 typedef T FlowMap; 180 180 static FlowMap *createFlowMap(const Digraph&) { 181 181 LEMON_ASSERT(false, "FlowMap is not initialized"); 182 182 return 0; 183 183 } … … 190 190 /// type 191 191 template <typename T> 192 struct SetFlowMap 192 struct SetFlowMap 193 193 : public EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > { 194 194 typedef EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > Create; … … 198 198 199 199 protected: 200 200 201 201 EdmondsKarp() {} 202 202 … … 205 205 /// \brief The constructor of the class. 206 206 /// 207 /// The constructor of the class. 208 /// \param digraph The digraph the algorithm runs on. 209 /// \param capacity The capacity of the arcs. 207 /// The constructor of the class. 208 /// \param digraph The digraph the algorithm runs on. 209 /// \param capacity The capacity of the arcs. 210 210 /// \param source The source node. 211 211 /// \param target The target node. 212 212 EdmondsKarp(const Digraph& digraph, const CapacityMap& capacity, 213 213 Node source, Node target) 214 214 : _graph(digraph), _capacity(&capacity), _source(source), _target(target), 215 215 _flow(0), _local_flow(false), _pred(0), _tolerance(), _flow_value() 216 216 { 217 217 LEMON_ASSERT(_source != _target, … … 245 245 EdmondsKarp& flowMap(FlowMap& map) { 246 246 if (_local_flow) { 247 248 247 delete _flow; 248 _local_flow = false; 249 249 } 250 250 _flow = ↦ … … 277 277 _tolerance = tolerance; 278 278 return *this; 279 } 279 } 280 280 281 281 /// \brief Returns a const reference to the tolerance. … … 285 285 const Tolerance& tolerance() const { 286 286 return _tolerance; 287 } 287 } 288 288 289 289 /// \name Execution control … … 292 292 /// you have to call one of the \ref init() functions first, then 293 293 /// \ref start() or multiple times the \ref augment() function. 294 294 295 295 ///@{ 296 296 … … 306 306 _flow_value = 0; 307 307 } 308 308 309 309 /// \brief Initializes the algorithm using the given flow map. 310 310 /// … … 318 318 createStructures(); 319 319 for (ArcIt e(_graph); e != INVALID; ++e) { 320 320 _flow->set(e, flowMap[e]); 321 321 } 322 322 _flow_value = 0; … … 335 335 /// contain a feasible flow, i.e. at each node excluding the source 336 336 /// and the target, the incoming flow should be equal to the 337 /// outgoing flow. 337 /// outgoing flow. 338 338 /// \return \c false when the given \c flowMap does not contain a 339 339 /// feasible flow. … … 342 342 createStructures(); 343 343 for (ArcIt e(_graph); e != INVALID; ++e) { 344 344 _flow->set(e, flowMap[e]); 345 345 } 346 346 for (NodeIt it(_graph); it != INVALID; ++it) { … … 373 373 374 374 /// \brief Augments the solution along a shortest path. 375 /// 375 /// 376 376 /// Augments the solution along a shortest path. This function searches a 377 377 /// shortest path between the source and the target … … 384 384 bool augment() { 385 385 for (NodeIt n(_graph); n != INVALID; ++n) { 386 387 } 388 386 _pred->set(n, INVALID); 387 } 388 389 389 int first = 0, last = 1; 390 390 391 391 _queue[0] = _source; 392 392 _pred->set(_source, OutArcIt(_graph, _source)); 393 393 394 394 while (first != last && (*_pred)[_target] == INVALID) { 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 395 Node n = _queue[first++]; 396 397 for (OutArcIt e(_graph, n); e != INVALID; ++e) { 398 Value rem = (*_capacity)[e] - (*_flow)[e]; 399 Node t = _graph.target(e); 400 if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) { 401 _pred->set(t, e); 402 _queue[last++] = t; 403 } 404 } 405 for (InArcIt e(_graph, n); e != INVALID; ++e) { 406 Value rem = (*_flow)[e]; 407 Node t = _graph.source(e); 408 if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) { 409 _pred->set(t, e); 410 _queue[last++] = t; 411 } 412 } 413 413 } 414 414 415 415 if ((*_pred)[_target] != INVALID) { 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 n = _graph.target(e); 431 } 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 n = _graph.target(e); 447 } 448 449 450 _flow_value += prem; 451 416 Node n = _target; 417 Arc e = (*_pred)[n]; 418 419 Value prem = (*_capacity)[e] - (*_flow)[e]; 420 n = _graph.source(e); 421 while (n != _source) { 422 e = (*_pred)[n]; 423 if (_graph.target(e) == n) { 424 Value rem = (*_capacity)[e] - (*_flow)[e]; 425 if (rem < prem) prem = rem; 426 n = _graph.source(e); 427 } else { 428 Value rem = (*_flow)[e]; 429 if (rem < prem) prem = rem; 430 n = _graph.target(e); 431 } 432 } 433 434 n = _target; 435 e = (*_pred)[n]; 436 437 _flow->set(e, (*_flow)[e] + prem); 438 n = _graph.source(e); 439 while (n != _source) { 440 e = (*_pred)[n]; 441 if (_graph.target(e) == n) { 442 _flow->set(e, (*_flow)[e] + prem); 443 n = _graph.source(e); 444 } else { 445 _flow->set(e, (*_flow)[e] - prem); 446 n = _graph.target(e); 447 } 448 } 449 450 _flow_value += prem; 451 return true; 452 452 } else { 453 453 return false; 454 454 } 455 455 } … … 458 458 /// 459 459 /// Executes the algorithm by performing augmenting phases until the 460 /// optimal solution is reached. 460 /// optimal solution is reached. 461 461 /// \pre One of the \ref init() functions must be called before 462 462 /// using this function. … … 466 466 467 467 /// \brief Runs the algorithm. 468 /// 468 /// 469 469 /// Runs the Edmonds-Karp algorithm. 470 470 /// \note ek.run() is just a shortcut of the following code. 471 ///\code 471 ///\code 472 472 /// ek.init(); 473 473 /// ek.start(); … … 484 484 /// functions.\n 485 485 /// Either \ref run() or \ref start() should be called before using them. 486 486 487 487 ///@{ 488 488 … … 543 543 void minCutMap(CutMap& cutMap) const { 544 544 for (NodeIt n(_graph); n != INVALID; ++n) { 545 545 cutMap.set(n, (*_pred)[n] != INVALID); 546 546 } 547 547 cutMap.set(_source, true); 548 } 548 } 549 549 550 550 /// @}
Note: See TracChangeset
for help on using the changeset viewer.