|
1 /* -*- C++ -*- |
|
2 * |
|
3 * This file is a part of LEMON, a generic C++ optimization library |
|
4 * |
|
5 * Copyright (C) 2003-2007 |
|
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 #ifndef LEMON_GOLDBERG_TARJAN_H |
|
20 #define LEMON_GOLDBERG_TARJAN_H |
|
21 |
|
22 #include <vector> |
|
23 #include <queue> |
|
24 |
|
25 #include <lemon/error.h> |
|
26 #include <lemon/bits/invalid.h> |
|
27 #include <lemon/tolerance.h> |
|
28 #include <lemon/maps.h> |
|
29 #include <lemon/graph_utils.h> |
|
30 #include <lemon/dynamic_tree.h> |
|
31 #include <limits> |
|
32 |
|
33 /// \file |
|
34 /// \ingroup max_flow |
|
35 /// \brief Implementation of the preflow algorithm. |
|
36 |
|
37 namespace lemon { |
|
38 |
|
39 /// \brief Default traits class of GoldbergTarjan class. |
|
40 /// |
|
41 /// Default traits class of GoldbergTarjan class. |
|
42 /// \param _Graph Graph type. |
|
43 /// \param _CapacityMap Type of capacity map. |
|
44 template <typename _Graph, typename _CapacityMap> |
|
45 struct GoldbergTarjanDefaultTraits { |
|
46 |
|
47 /// \brief The graph type the algorithm runs on. |
|
48 typedef _Graph Graph; |
|
49 |
|
50 /// \brief The type of the map that stores the edge capacities. |
|
51 /// |
|
52 /// The type of the map that stores the edge capacities. |
|
53 /// It must meet the \ref concepts::ReadMap "ReadMap" concept. |
|
54 typedef _CapacityMap CapacityMap; |
|
55 |
|
56 /// \brief The type of the length of the edges. |
|
57 typedef typename CapacityMap::Value Value; |
|
58 |
|
59 /// \brief The map type that stores the flow values. |
|
60 /// |
|
61 /// The map type that stores the flow values. |
|
62 /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept. |
|
63 typedef typename Graph::template EdgeMap<Value> FlowMap; |
|
64 |
|
65 /// \brief Instantiates a FlowMap. |
|
66 /// |
|
67 /// This function instantiates a \ref FlowMap. |
|
68 /// \param graph The graph, to which we would like to define the flow map. |
|
69 static FlowMap* createFlowMap(const Graph& graph) { |
|
70 return new FlowMap(graph); |
|
71 } |
|
72 |
|
73 /// \brief The eleavator type used by GoldbergTarjan algorithm. |
|
74 /// |
|
75 /// The elevator type used by GoldbergTarjan algorithm. |
|
76 /// |
|
77 /// \sa Elevator |
|
78 /// \sa LinkedElevator |
|
79 typedef LinkedElevator<Graph, typename Graph::Node> Elevator; |
|
80 |
|
81 /// \brief Instantiates an Elevator. |
|
82 /// |
|
83 /// This function instantiates a \ref Elevator. |
|
84 /// \param graph The graph, to which we would like to define the elevator. |
|
85 /// \param max_level The maximum level of the elevator. |
|
86 static Elevator* createElevator(const Graph& graph, int max_level) { |
|
87 return new Elevator(graph, max_level); |
|
88 } |
|
89 |
|
90 /// \brief The tolerance used by the algorithm |
|
91 /// |
|
92 /// The tolerance used by the algorithm to handle inexact computation. |
|
93 typedef Tolerance<Value> Tolerance; |
|
94 |
|
95 }; |
|
96 |
|
97 /// \ingroup max_flow |
|
98 /// \brief Goldberg-Tarjan algorithms class. |
|
99 /// |
|
100 /// This class provides an implementation of the \e GoldbergTarjan |
|
101 /// \e algorithm producing a flow of maximum value in a directed |
|
102 /// graph. The GoldbergTarjan algorithm is a theoretical improvement |
|
103 /// of the Goldberg's \ref Preflow "preflow" algorithm by using the \ref |
|
104 /// DynamicTree "dynamic tree" data structure of Sleator and Tarjan. |
|
105 /// |
|
106 /// The original preflow algorithm with \e "highest label" or \e |
|
107 /// FIFO heuristic has \f$O(n^3)\f$ time complexity. The current |
|
108 /// algorithm improved this complexity to |
|
109 /// \f$O(nm\log(\frac{n^2}{m}))\f$. The algorithm builds limited |
|
110 /// size dynamic trees on the residual graph, which can be used to |
|
111 /// make multilevel push operations and gives a better bound on the |
|
112 /// number of non-saturating pushes. |
|
113 /// |
|
114 /// \param Graph The directed graph type the algorithm runs on. |
|
115 /// \param CapacityMap The capacity map type. |
|
116 /// \param _Traits Traits class to set various data types used by |
|
117 /// the algorithm. The default traits class is \ref |
|
118 /// GoldbergTarjanDefaultTraits. See \ref |
|
119 /// GoldbergTarjanDefaultTraits for the documentation of a |
|
120 /// Goldberg-Tarjan traits class. |
|
121 /// |
|
122 /// \author Tamas Hamori and Balazs Dezso |
|
123 #ifdef DOXYGEN |
|
124 template <typename _Graph, typename _CapacityMap, typename _Traits> |
|
125 #else |
|
126 template <typename _Graph, |
|
127 typename _CapacityMap = typename _Graph::template EdgeMap<int>, |
|
128 typename _Traits = |
|
129 GoldbergTarjanDefaultTraits<_Graph, _CapacityMap> > |
|
130 #endif |
|
131 class GoldbergTarjan { |
|
132 public: |
|
133 |
|
134 typedef _Traits Traits; |
|
135 typedef typename Traits::Graph Graph; |
|
136 typedef typename Traits::CapacityMap CapacityMap; |
|
137 typedef typename Traits::Value Value; |
|
138 |
|
139 typedef typename Traits::FlowMap FlowMap; |
|
140 typedef typename Traits::Elevator Elevator; |
|
141 typedef typename Traits::Tolerance Tolerance; |
|
142 |
|
143 protected: |
|
144 |
|
145 GRAPH_TYPEDEFS(typename Graph); |
|
146 |
|
147 typedef typename Graph::template NodeMap<Node> NodeNodeMap; |
|
148 typedef typename Graph::template NodeMap<int> IntNodeMap; |
|
149 |
|
150 typedef typename Graph::template NodeMap<Edge> EdgeNodeMap; |
|
151 typedef typename Graph::template EdgeMap<Edge> EdgeEdgeMap; |
|
152 |
|
153 typedef typename std::vector<Node> VecNode; |
|
154 |
|
155 typedef DynamicTree<Value,IntNodeMap,Tolerance> DynTree; |
|
156 |
|
157 const Graph& _graph; |
|
158 const CapacityMap* _capacity; |
|
159 int _node_num; //the number of nodes of G |
|
160 |
|
161 Node _source; |
|
162 Node _target; |
|
163 |
|
164 FlowMap* _flow; |
|
165 bool _local_flow; |
|
166 |
|
167 Elevator* _level; |
|
168 bool _local_level; |
|
169 |
|
170 typedef typename Graph::template NodeMap<Value> ExcessMap; |
|
171 ExcessMap* _excess; |
|
172 |
|
173 Tolerance _tolerance; |
|
174 |
|
175 bool _phase; |
|
176 |
|
177 // constant for treesize |
|
178 static const double _tree_bound = 2; |
|
179 int _max_tree_size; |
|
180 |
|
181 //tags for the dynamic tree |
|
182 DynTree *_dt; |
|
183 //datastructure of dyanamic tree |
|
184 IntNodeMap *_dt_index; |
|
185 //datastrucure for solution of the communication between the two class |
|
186 EdgeNodeMap *_dt_edges; |
|
187 //nodeMap for storing the outgoing edge from the node in the tree |
|
188 |
|
189 //max of the type Value |
|
190 const Value _max_value; |
|
191 |
|
192 public: |
|
193 |
|
194 typedef GoldbergTarjan Create; |
|
195 |
|
196 ///\name Named template parameters |
|
197 |
|
198 ///@{ |
|
199 |
|
200 template <typename _FlowMap> |
|
201 struct DefFlowMapTraits : public Traits { |
|
202 typedef _FlowMap FlowMap; |
|
203 static FlowMap *createFlowMap(const Graph&) { |
|
204 throw UninitializedParameter(); |
|
205 } |
|
206 }; |
|
207 |
|
208 /// \brief \ref named-templ-param "Named parameter" for setting |
|
209 /// FlowMap type |
|
210 /// |
|
211 /// \ref named-templ-param "Named parameter" for setting FlowMap |
|
212 /// type |
|
213 template <typename _FlowMap> |
|
214 struct DefFlowMap |
|
215 : public GoldbergTarjan<Graph, CapacityMap, |
|
216 DefFlowMapTraits<_FlowMap> > { |
|
217 typedef GoldbergTarjan<Graph, CapacityMap, |
|
218 DefFlowMapTraits<_FlowMap> > Create; |
|
219 }; |
|
220 |
|
221 template <typename _Elevator> |
|
222 struct DefElevatorTraits : public Traits { |
|
223 typedef _Elevator Elevator; |
|
224 static Elevator *createElevator(const Graph&, int) { |
|
225 throw UninitializedParameter(); |
|
226 } |
|
227 }; |
|
228 |
|
229 /// \brief \ref named-templ-param "Named parameter" for setting |
|
230 /// Elevator type |
|
231 /// |
|
232 /// \ref named-templ-param "Named parameter" for setting Elevator |
|
233 /// type |
|
234 template <typename _Elevator> |
|
235 struct DefElevator |
|
236 : public GoldbergTarjan<Graph, CapacityMap, |
|
237 DefElevatorTraits<_Elevator> > { |
|
238 typedef GoldbergTarjan<Graph, CapacityMap, |
|
239 DefElevatorTraits<_Elevator> > Create; |
|
240 }; |
|
241 |
|
242 template <typename _Elevator> |
|
243 struct DefStandardElevatorTraits : public Traits { |
|
244 typedef _Elevator Elevator; |
|
245 static Elevator *createElevator(const Graph& graph, int max_level) { |
|
246 return new Elevator(graph, max_level); |
|
247 } |
|
248 }; |
|
249 |
|
250 /// \brief \ref named-templ-param "Named parameter" for setting |
|
251 /// Elevator type |
|
252 /// |
|
253 /// \ref named-templ-param "Named parameter" for setting Elevator |
|
254 /// type. The Elevator should be standard constructor interface, ie. |
|
255 /// the graph and the maximum level should be passed to it. |
|
256 template <typename _Elevator> |
|
257 struct DefStandardElevator |
|
258 : public GoldbergTarjan<Graph, CapacityMap, |
|
259 DefStandardElevatorTraits<_Elevator> > { |
|
260 typedef GoldbergTarjan<Graph, CapacityMap, |
|
261 DefStandardElevatorTraits<_Elevator> > Create; |
|
262 }; |
|
263 |
|
264 |
|
265 ///\ref Exception for the case when s=t. |
|
266 |
|
267 ///\ref Exception for the case when the source equals the target. |
|
268 class InvalidArgument : public lemon::LogicError { |
|
269 public: |
|
270 virtual const char* what() const throw() { |
|
271 return "lemon::GoldbergTarjan::InvalidArgument"; |
|
272 } |
|
273 }; |
|
274 |
|
275 public: |
|
276 |
|
277 /// \brief The constructor of the class. |
|
278 /// |
|
279 /// The constructor of the class. |
|
280 /// \param graph The directed graph the algorithm runs on. |
|
281 /// \param capacity The capacity of the edges. |
|
282 /// \param source The source node. |
|
283 /// \param target The target node. |
|
284 /// Except the graph, all of these parameters can be reset by |
|
285 /// calling \ref source, \ref target, \ref capacityMap and \ref |
|
286 /// flowMap, resp. |
|
287 GoldbergTarjan(const Graph& graph, const CapacityMap& capacity, |
|
288 Node source, Node target) |
|
289 : _graph(graph), _capacity(&capacity), |
|
290 _node_num(), _source(source), _target(target), |
|
291 _flow(0), _local_flow(false), |
|
292 _level(0), _local_level(false), |
|
293 _excess(0), _tolerance(), |
|
294 _phase(), _max_tree_size(), |
|
295 _dt(0), _dt_index(0), _dt_edges(0), |
|
296 _max_value(std::numeric_limits<Value>::max()) { |
|
297 if (_source == _target) throw InvalidArgument(); |
|
298 } |
|
299 |
|
300 /// \brief Destrcutor. |
|
301 /// |
|
302 /// Destructor. |
|
303 ~GoldbergTarjan() { |
|
304 destroyStructures(); |
|
305 } |
|
306 |
|
307 /// \brief Sets the capacity map. |
|
308 /// |
|
309 /// Sets the capacity map. |
|
310 /// \return \c (*this) |
|
311 GoldbergTarjan& capacityMap(const CapacityMap& map) { |
|
312 _capacity = ↦ |
|
313 return *this; |
|
314 } |
|
315 |
|
316 /// \brief Sets the flow map. |
|
317 /// |
|
318 /// Sets the flow map. |
|
319 /// \return \c (*this) |
|
320 GoldbergTarjan& flowMap(FlowMap& map) { |
|
321 if (_local_flow) { |
|
322 delete _flow; |
|
323 _local_flow = false; |
|
324 } |
|
325 _flow = ↦ |
|
326 return *this; |
|
327 } |
|
328 |
|
329 /// \brief Returns the flow map. |
|
330 /// |
|
331 /// \return The flow map. |
|
332 const FlowMap& flowMap() { |
|
333 return *_flow; |
|
334 } |
|
335 |
|
336 /// \brief Sets the elevator. |
|
337 /// |
|
338 /// Sets the elevator. |
|
339 /// \return \c (*this) |
|
340 GoldbergTarjan& elevator(Elevator& elevator) { |
|
341 if (_local_level) { |
|
342 delete _level; |
|
343 _local_level = false; |
|
344 } |
|
345 _level = &elevator; |
|
346 return *this; |
|
347 } |
|
348 |
|
349 /// \brief Returns the elevator. |
|
350 /// |
|
351 /// \return The elevator. |
|
352 const Elevator& elevator() { |
|
353 return *_level; |
|
354 } |
|
355 |
|
356 /// \brief Sets the source node. |
|
357 /// |
|
358 /// Sets the source node. |
|
359 /// \return \c (*this) |
|
360 GoldbergTarjan& source(const Node& node) { |
|
361 _source = node; |
|
362 return *this; |
|
363 } |
|
364 |
|
365 /// \brief Sets the target node. |
|
366 /// |
|
367 /// Sets the target node. |
|
368 /// \return \c (*this) |
|
369 GoldbergTarjan& target(const Node& node) { |
|
370 _target = node; |
|
371 return *this; |
|
372 } |
|
373 |
|
374 /// \brief Sets the tolerance used by algorithm. |
|
375 /// |
|
376 /// Sets the tolerance used by algorithm. |
|
377 GoldbergTarjan& tolerance(const Tolerance& tolerance) const { |
|
378 _tolerance = tolerance; |
|
379 if (_dt) { |
|
380 _dt->tolerance(_tolerance); |
|
381 } |
|
382 return *this; |
|
383 } |
|
384 |
|
385 /// \brief Returns the tolerance used by algorithm. |
|
386 /// |
|
387 /// Returns the tolerance used by algorithm. |
|
388 const Tolerance& tolerance() const { |
|
389 return tolerance; |
|
390 } |
|
391 |
|
392 |
|
393 private: |
|
394 |
|
395 void createStructures() { |
|
396 _node_num = countNodes(_graph); |
|
397 |
|
398 _max_tree_size = (double(_node_num) * double(_node_num)) / |
|
399 double(countEdges(_graph)); |
|
400 |
|
401 if (!_flow) { |
|
402 _flow = Traits::createFlowMap(_graph); |
|
403 _local_flow = true; |
|
404 } |
|
405 if (!_level) { |
|
406 _level = Traits::createElevator(_graph, _node_num); |
|
407 _local_level = true; |
|
408 } |
|
409 if (!_excess) { |
|
410 _excess = new ExcessMap(_graph); |
|
411 } |
|
412 if (!_dt_index && !_dt) { |
|
413 _dt_index = new IntNodeMap(_graph); |
|
414 _dt = new DynTree(*_dt_index, _tolerance); |
|
415 } |
|
416 if (!_dt_edges) { |
|
417 _dt_edges = new EdgeNodeMap(_graph); |
|
418 } |
|
419 } |
|
420 |
|
421 void destroyStructures() { |
|
422 if (_local_flow) { |
|
423 delete _flow; |
|
424 } |
|
425 if (_local_level) { |
|
426 delete _level; |
|
427 } |
|
428 if (_excess) { |
|
429 delete _excess; |
|
430 } |
|
431 if (_dt) { |
|
432 delete _dt; |
|
433 } |
|
434 if (_dt_index) { |
|
435 delete _dt_index; |
|
436 } |
|
437 if (_dt_edges) { |
|
438 delete _dt_edges; |
|
439 } |
|
440 } |
|
441 |
|
442 bool sendOut(Node n, Value& excess) { |
|
443 |
|
444 Node w = _dt->findRoot(n); |
|
445 |
|
446 while (w != n) { |
|
447 |
|
448 Value rem; |
|
449 Node u = _dt->findCost(n, rem); |
|
450 |
|
451 if (_tolerance.positive(rem) && !_level->active(w) && w != _target) { |
|
452 _level->activate(w); |
|
453 } |
|
454 |
|
455 if (!_tolerance.less(rem, excess)) { |
|
456 _dt->addCost(n, - excess); |
|
457 _excess->set(w, (*_excess)[w] + excess); |
|
458 excess = 0; |
|
459 return true; |
|
460 } |
|
461 |
|
462 |
|
463 _dt->addCost(n, - rem); |
|
464 |
|
465 excess -= rem; |
|
466 _excess->set(w, (*_excess)[w] + rem); |
|
467 |
|
468 _dt->cut(u); |
|
469 _dt->addCost(u, _max_value); |
|
470 |
|
471 Edge e = (*_dt_edges)[u]; |
|
472 _dt_edges->set(u, INVALID); |
|
473 |
|
474 if (u == _graph.source(e)) { |
|
475 _flow->set(e, (*_capacity)[e]); |
|
476 } else { |
|
477 _flow->set(e, 0); |
|
478 } |
|
479 |
|
480 w = _dt->findRoot(n); |
|
481 } |
|
482 return false; |
|
483 } |
|
484 |
|
485 bool sendIn(Node n, Value& excess) { |
|
486 |
|
487 Node w = _dt->findRoot(n); |
|
488 |
|
489 while (w != n) { |
|
490 |
|
491 Value rem; |
|
492 Node u = _dt->findCost(n, rem); |
|
493 |
|
494 if (_tolerance.positive(rem) && !_level->active(w) && w != _source) { |
|
495 _level->activate(w); |
|
496 } |
|
497 |
|
498 if (!_tolerance.less(rem, excess)) { |
|
499 _dt->addCost(n, - excess); |
|
500 _excess->set(w, (*_excess)[w] + excess); |
|
501 excess = 0; |
|
502 return true; |
|
503 } |
|
504 |
|
505 |
|
506 _dt->addCost(n, - rem); |
|
507 |
|
508 excess -= rem; |
|
509 _excess->set(w, (*_excess)[w] + rem); |
|
510 |
|
511 _dt->cut(u); |
|
512 _dt->addCost(u, _max_value); |
|
513 |
|
514 Edge e = (*_dt_edges)[u]; |
|
515 _dt_edges->set(u, INVALID); |
|
516 |
|
517 if (u == _graph.source(e)) { |
|
518 _flow->set(e, (*_capacity)[e]); |
|
519 } else { |
|
520 _flow->set(e, 0); |
|
521 } |
|
522 |
|
523 w = _dt->findRoot(n); |
|
524 } |
|
525 return false; |
|
526 } |
|
527 |
|
528 void cutChildren(Node n) { |
|
529 |
|
530 for (OutEdgeIt e(_graph, n); e != INVALID; ++e) { |
|
531 |
|
532 Node v = _graph.target(e); |
|
533 |
|
534 if ((*_dt_edges)[v] != INVALID && (*_dt_edges)[v] == e) { |
|
535 _dt->cut(v); |
|
536 _dt_edges->set(v, INVALID); |
|
537 Value rem; |
|
538 _dt->findCost(v, rem); |
|
539 _dt->addCost(v, - rem); |
|
540 _dt->addCost(v, _max_value); |
|
541 _flow->set(e, rem); |
|
542 |
|
543 } |
|
544 } |
|
545 |
|
546 for (InEdgeIt e(_graph, n); e != INVALID; ++e) { |
|
547 |
|
548 Node v = _graph.source(e); |
|
549 |
|
550 if ((*_dt_edges)[v] != INVALID && (*_dt_edges)[v] == e) { |
|
551 _dt->cut(v); |
|
552 _dt_edges->set(v, INVALID); |
|
553 Value rem; |
|
554 _dt->findCost(v, rem); |
|
555 _dt->addCost(v, - rem); |
|
556 _dt->addCost(v, _max_value); |
|
557 _flow->set(e, (*_capacity)[e] - rem); |
|
558 |
|
559 } |
|
560 } |
|
561 } |
|
562 |
|
563 void extractTrees() { |
|
564 for (NodeIt n(_graph); n != INVALID; ++n) { |
|
565 |
|
566 Node w = _dt->findRoot(n); |
|
567 |
|
568 while (w != n) { |
|
569 |
|
570 Value rem; |
|
571 Node u = _dt->findCost(n, rem); |
|
572 |
|
573 _dt->cut(u); |
|
574 _dt->addCost(u, - rem); |
|
575 _dt->addCost(u, _max_value); |
|
576 |
|
577 Edge e = (*_dt_edges)[u]; |
|
578 _dt_edges->set(u, INVALID); |
|
579 |
|
580 if (u == _graph.source(e)) { |
|
581 _flow->set(e, (*_capacity)[e] - rem); |
|
582 } else { |
|
583 _flow->set(e, rem); |
|
584 } |
|
585 |
|
586 w = _dt->findRoot(n); |
|
587 } |
|
588 } |
|
589 } |
|
590 |
|
591 public: |
|
592 |
|
593 /// \name Execution control The simplest way to execute the |
|
594 /// algorithm is to use one of the member functions called \c |
|
595 /// run(). |
|
596 /// \n |
|
597 /// If you need more control on initial solution or |
|
598 /// execution then you have to call one \ref init() function and then |
|
599 /// the startFirstPhase() and if you need the startSecondPhase(). |
|
600 |
|
601 ///@{ |
|
602 |
|
603 /// \brief Initializes the internal data structures. |
|
604 /// |
|
605 /// Initializes the internal data structures. |
|
606 /// |
|
607 void init() { |
|
608 createStructures(); |
|
609 |
|
610 for (NodeIt n(_graph); n != INVALID; ++n) { |
|
611 _excess->set(n, 0); |
|
612 } |
|
613 |
|
614 for (EdgeIt e(_graph); e != INVALID; ++e) { |
|
615 _flow->set(e, 0); |
|
616 } |
|
617 |
|
618 _dt->clear(); |
|
619 for (NodeIt v(_graph); v != INVALID; ++v) { |
|
620 (*_dt_edges)[v] = INVALID; |
|
621 _dt->makeTree(v); |
|
622 _dt->addCost(v, _max_value); |
|
623 } |
|
624 |
|
625 typename Graph::template NodeMap<bool> reached(_graph, false); |
|
626 |
|
627 _level->initStart(); |
|
628 _level->initAddItem(_target); |
|
629 |
|
630 std::vector<Node> queue; |
|
631 reached.set(_source, true); |
|
632 |
|
633 queue.push_back(_target); |
|
634 reached.set(_target, true); |
|
635 while (!queue.empty()) { |
|
636 _level->initNewLevel(); |
|
637 std::vector<Node> nqueue; |
|
638 for (int i = 0; i < int(queue.size()); ++i) { |
|
639 Node n = queue[i]; |
|
640 for (InEdgeIt e(_graph, n); e != INVALID; ++e) { |
|
641 Node u = _graph.source(e); |
|
642 if (!reached[u] && _tolerance.positive((*_capacity)[e])) { |
|
643 reached.set(u, true); |
|
644 _level->initAddItem(u); |
|
645 nqueue.push_back(u); |
|
646 } |
|
647 } |
|
648 } |
|
649 queue.swap(nqueue); |
|
650 } |
|
651 _level->initFinish(); |
|
652 |
|
653 for (OutEdgeIt e(_graph, _source); e != INVALID; ++e) { |
|
654 if (_tolerance.positive((*_capacity)[e])) { |
|
655 Node u = _graph.target(e); |
|
656 if ((*_level)[u] == _level->maxLevel()) continue; |
|
657 _flow->set(e, (*_capacity)[e]); |
|
658 _excess->set(u, (*_excess)[u] + (*_capacity)[e]); |
|
659 if (u != _target && !_level->active(u)) { |
|
660 _level->activate(u); |
|
661 } |
|
662 } |
|
663 } |
|
664 } |
|
665 |
|
666 /// \brief Starts the first phase of the preflow algorithm. |
|
667 /// |
|
668 /// The preflow algorithm consists of two phases, this method runs |
|
669 /// the first phase. After the first phase the maximum flow value |
|
670 /// and a minimum value cut can already be computed, although a |
|
671 /// maximum flow is not yet obtained. So after calling this method |
|
672 /// \ref flowValue() returns the value of a maximum flow and \ref |
|
673 /// minCut() returns a minimum cut. |
|
674 /// \pre One of the \ref init() functions should be called. |
|
675 void startFirstPhase() { |
|
676 _phase = true; |
|
677 Node n; |
|
678 |
|
679 while ((n = _level->highestActive()) != INVALID) { |
|
680 Value excess = (*_excess)[n]; |
|
681 int level = _level->highestActiveLevel(); |
|
682 int new_level = _level->maxLevel(); |
|
683 |
|
684 if (_dt->findRoot(n) != n) { |
|
685 if (sendOut(n, excess)) goto no_more_push; |
|
686 } |
|
687 |
|
688 for (OutEdgeIt e(_graph, n); e != INVALID; ++e) { |
|
689 Value rem = (*_capacity)[e] - (*_flow)[e]; |
|
690 Node v = _graph.target(e); |
|
691 |
|
692 if (!_tolerance.positive(rem) && (*_dt_edges)[v] != e) continue; |
|
693 |
|
694 if ((*_level)[v] < level) { |
|
695 |
|
696 if (_dt->findSize(n) + _dt->findSize(v) < |
|
697 _tree_bound * _max_tree_size) { |
|
698 _dt->addCost(n, -_max_value); |
|
699 _dt->addCost(n, rem); |
|
700 _dt->link(n, v); |
|
701 _dt_edges->set(n, e); |
|
702 if (sendOut(n, excess)) goto no_more_push; |
|
703 } else { |
|
704 if (!_level->active(v) && v != _target) { |
|
705 _level->activate(v); |
|
706 } |
|
707 if (!_tolerance.less(rem, excess)) { |
|
708 _flow->set(e, (*_flow)[e] + excess); |
|
709 _excess->set(v, (*_excess)[v] + excess); |
|
710 excess = 0; |
|
711 goto no_more_push; |
|
712 } else { |
|
713 excess -= rem; |
|
714 _excess->set(v, (*_excess)[v] + rem); |
|
715 _flow->set(e, (*_capacity)[e]); |
|
716 } |
|
717 } |
|
718 } else if (new_level > (*_level)[v]) { |
|
719 new_level = (*_level)[v]; |
|
720 } |
|
721 } |
|
722 |
|
723 for (InEdgeIt e(_graph, n); e != INVALID; ++e) { |
|
724 Value rem = (*_flow)[e]; |
|
725 Node v = _graph.source(e); |
|
726 if (!_tolerance.positive(rem) && (*_dt_edges)[v] != e) continue; |
|
727 |
|
728 if ((*_level)[v] < level) { |
|
729 |
|
730 if (_dt->findSize(n) + _dt->findSize(v) < |
|
731 _tree_bound * _max_tree_size) { |
|
732 _dt->addCost(n, - _max_value); |
|
733 _dt->addCost(n, rem); |
|
734 _dt->link(n, v); |
|
735 _dt_edges->set(n, e); |
|
736 if (sendOut(n, excess)) goto no_more_push; |
|
737 } else { |
|
738 if (!_level->active(v) && v != _target) { |
|
739 _level->activate(v); |
|
740 } |
|
741 if (!_tolerance.less(rem, excess)) { |
|
742 _flow->set(e, (*_flow)[e] - excess); |
|
743 _excess->set(v, (*_excess)[v] + excess); |
|
744 excess = 0; |
|
745 goto no_more_push; |
|
746 } else { |
|
747 excess -= rem; |
|
748 _excess->set(v, (*_excess)[v] + rem); |
|
749 _flow->set(e, 0); |
|
750 } |
|
751 } |
|
752 } else if (new_level > (*_level)[v]) { |
|
753 new_level = (*_level)[v]; |
|
754 } |
|
755 } |
|
756 |
|
757 no_more_push: |
|
758 |
|
759 _excess->set(n, excess); |
|
760 |
|
761 if (excess != 0) { |
|
762 cutChildren(n); |
|
763 if (new_level + 1 < _level->maxLevel()) { |
|
764 _level->liftHighestActive(new_level + 1); |
|
765 } else { |
|
766 _level->liftHighestActiveToTop(); |
|
767 } |
|
768 if (_level->emptyLevel(level)) { |
|
769 _level->liftToTop(level); |
|
770 } |
|
771 } else { |
|
772 _level->deactivate(n); |
|
773 } |
|
774 } |
|
775 extractTrees(); |
|
776 } |
|
777 |
|
778 /// \brief Starts the second phase of the preflow algorithm. |
|
779 /// |
|
780 /// The preflow algorithm consists of two phases, this method runs |
|
781 /// the second phase. After calling \ref init() and \ref |
|
782 /// startFirstPhase() and then \ref startSecondPhase(), \ref |
|
783 /// flowMap() return a maximum flow, \ref flowValue() returns the |
|
784 /// value of a maximum flow, \ref minCut() returns a minimum cut |
|
785 /// \pre The \ref init() and startFirstPhase() functions should be |
|
786 /// called before. |
|
787 void startSecondPhase() { |
|
788 _phase = false; |
|
789 |
|
790 typename Graph::template NodeMap<bool> reached(_graph, false); |
|
791 for (NodeIt n(_graph); n != INVALID; ++n) { |
|
792 reached.set(n, (*_level)[n] < _level->maxLevel()); |
|
793 } |
|
794 |
|
795 _level->initStart(); |
|
796 _level->initAddItem(_source); |
|
797 |
|
798 std::vector<Node> queue; |
|
799 queue.push_back(_source); |
|
800 reached.set(_source, true); |
|
801 |
|
802 while (!queue.empty()) { |
|
803 _level->initNewLevel(); |
|
804 std::vector<Node> nqueue; |
|
805 for (int i = 0; i < int(queue.size()); ++i) { |
|
806 Node n = queue[i]; |
|
807 for (OutEdgeIt e(_graph, n); e != INVALID; ++e) { |
|
808 Node v = _graph.target(e); |
|
809 if (!reached[v] && _tolerance.positive((*_flow)[e])) { |
|
810 reached.set(v, true); |
|
811 _level->initAddItem(v); |
|
812 nqueue.push_back(v); |
|
813 } |
|
814 } |
|
815 for (InEdgeIt e(_graph, n); e != INVALID; ++e) { |
|
816 Node u = _graph.source(e); |
|
817 if (!reached[u] && |
|
818 _tolerance.positive((*_capacity)[e] - (*_flow)[e])) { |
|
819 reached.set(u, true); |
|
820 _level->initAddItem(u); |
|
821 nqueue.push_back(u); |
|
822 } |
|
823 } |
|
824 } |
|
825 queue.swap(nqueue); |
|
826 } |
|
827 _level->initFinish(); |
|
828 |
|
829 for (NodeIt n(_graph); n != INVALID; ++n) { |
|
830 if ((*_excess)[n] > 0 && _target != n) { |
|
831 _level->activate(n); |
|
832 } |
|
833 } |
|
834 |
|
835 Node n; |
|
836 |
|
837 while ((n = _level->highestActive()) != INVALID) { |
|
838 Value excess = (*_excess)[n]; |
|
839 int level = _level->highestActiveLevel(); |
|
840 int new_level = _level->maxLevel(); |
|
841 |
|
842 if (_dt->findRoot(n) != n) { |
|
843 if (sendIn(n, excess)) goto no_more_push; |
|
844 } |
|
845 |
|
846 for (OutEdgeIt e(_graph, n); e != INVALID; ++e) { |
|
847 Value rem = (*_capacity)[e] - (*_flow)[e]; |
|
848 Node v = _graph.target(e); |
|
849 |
|
850 if (!_tolerance.positive(rem) && (*_dt_edges)[v] != e) continue; |
|
851 |
|
852 if ((*_level)[v] < level) { |
|
853 |
|
854 if (_dt->findSize(n) + _dt->findSize(v) < |
|
855 _tree_bound * _max_tree_size) { |
|
856 _dt->addCost(n, -_max_value); |
|
857 _dt->addCost(n, rem); |
|
858 _dt->link(n, v); |
|
859 _dt_edges->set(n, e); |
|
860 if (sendIn(n, excess)) goto no_more_push; |
|
861 } else { |
|
862 if (!_level->active(v) && v != _source) { |
|
863 _level->activate(v); |
|
864 } |
|
865 if (!_tolerance.less(rem, excess)) { |
|
866 _flow->set(e, (*_flow)[e] + excess); |
|
867 _excess->set(v, (*_excess)[v] + excess); |
|
868 excess = 0; |
|
869 goto no_more_push; |
|
870 } else { |
|
871 excess -= rem; |
|
872 _excess->set(v, (*_excess)[v] + rem); |
|
873 _flow->set(e, (*_capacity)[e]); |
|
874 } |
|
875 } |
|
876 } else if (new_level > (*_level)[v]) { |
|
877 new_level = (*_level)[v]; |
|
878 } |
|
879 } |
|
880 |
|
881 for (InEdgeIt e(_graph, n); e != INVALID; ++e) { |
|
882 Value rem = (*_flow)[e]; |
|
883 Node v = _graph.source(e); |
|
884 if (!_tolerance.positive(rem) && (*_dt_edges)[v] != e) continue; |
|
885 |
|
886 if ((*_level)[v] < level) { |
|
887 |
|
888 if (_dt->findSize(n) + _dt->findSize(v) < |
|
889 _tree_bound * _max_tree_size) { |
|
890 _dt->addCost(n, - _max_value); |
|
891 _dt->addCost(n, rem); |
|
892 _dt->link(n, v); |
|
893 _dt_edges->set(n, e); |
|
894 if (sendIn(n, excess)) goto no_more_push; |
|
895 } else { |
|
896 if (!_level->active(v) && v != _source) { |
|
897 _level->activate(v); |
|
898 } |
|
899 if (!_tolerance.less(rem, excess)) { |
|
900 _flow->set(e, (*_flow)[e] - excess); |
|
901 _excess->set(v, (*_excess)[v] + excess); |
|
902 excess = 0; |
|
903 goto no_more_push; |
|
904 } else { |
|
905 excess -= rem; |
|
906 _excess->set(v, (*_excess)[v] + rem); |
|
907 _flow->set(e, 0); |
|
908 } |
|
909 } |
|
910 } else if (new_level > (*_level)[v]) { |
|
911 new_level = (*_level)[v]; |
|
912 } |
|
913 } |
|
914 |
|
915 no_more_push: |
|
916 |
|
917 _excess->set(n, excess); |
|
918 |
|
919 if (excess != 0) { |
|
920 cutChildren(n); |
|
921 if (new_level + 1 < _level->maxLevel()) { |
|
922 _level->liftHighestActive(new_level + 1); |
|
923 } else { |
|
924 _level->liftHighestActiveToTop(); |
|
925 } |
|
926 if (_level->emptyLevel(level)) { |
|
927 _level->liftToTop(level); |
|
928 } |
|
929 } else { |
|
930 _level->deactivate(n); |
|
931 } |
|
932 } |
|
933 extractTrees(); |
|
934 } |
|
935 |
|
936 /// \brief Runs the Goldberg-Tarjan algorithm. |
|
937 /// |
|
938 /// Runs the Goldberg-Tarjan algorithm. |
|
939 /// \note pf.run() is just a shortcut of the following code. |
|
940 /// \code |
|
941 /// pf.init(); |
|
942 /// pf.startFirstPhase(); |
|
943 /// pf.startSecondPhase(); |
|
944 /// \endcode |
|
945 void run() { |
|
946 init(); |
|
947 startFirstPhase(); |
|
948 startSecondPhase(); |
|
949 } |
|
950 |
|
951 /// \brief Runs the Goldberg-Tarjan algorithm to compute the minimum cut. |
|
952 /// |
|
953 /// Runs the Goldberg-Tarjan algorithm to compute the minimum cut. |
|
954 /// \note pf.runMinCut() is just a shortcut of the following code. |
|
955 /// \code |
|
956 /// pf.init(); |
|
957 /// pf.startFirstPhase(); |
|
958 /// \endcode |
|
959 void runMinCut() { |
|
960 init(); |
|
961 startFirstPhase(); |
|
962 } |
|
963 |
|
964 /// @} |
|
965 |
|
966 /// \name Query Functions |
|
967 /// The result of the %Dijkstra algorithm can be obtained using these |
|
968 /// functions.\n |
|
969 /// Before the use of these functions, |
|
970 /// either run() or start() must be called. |
|
971 |
|
972 ///@{ |
|
973 |
|
974 /// \brief Returns the value of the maximum flow. |
|
975 /// |
|
976 /// Returns the value of the maximum flow by returning the excess |
|
977 /// of the target node \c t. This value equals to the value of |
|
978 /// the maximum flow already after the first phase. |
|
979 Value flowValue() const { |
|
980 return (*_excess)[_target]; |
|
981 } |
|
982 |
|
983 /// \brief Returns true when the node is on the source side of minimum cut. |
|
984 /// |
|
985 /// Returns true when the node is on the source side of minimum |
|
986 /// cut. This method can be called both after running \ref |
|
987 /// startFirstPhase() and \ref startSecondPhase(). |
|
988 bool minCut(const Node& node) const { |
|
989 return ((*_level)[node] == _level->maxLevel()) == _phase; |
|
990 } |
|
991 |
|
992 /// \brief Returns a minimum value cut. |
|
993 /// |
|
994 /// Sets the \c cutMap to the characteristic vector of a minimum value |
|
995 /// cut. This method can be called both after running \ref |
|
996 /// startFirstPhase() and \ref startSecondPhase(). The result after second |
|
997 /// phase could be changed slightly if inexact computation is used. |
|
998 /// \pre The \c cutMap should be a bool-valued node-map. |
|
999 template <typename CutMap> |
|
1000 void minCutMap(CutMap& cutMap) const { |
|
1001 for (NodeIt n(_graph); n != INVALID; ++n) { |
|
1002 cutMap.set(n, minCut(n)); |
|
1003 } |
|
1004 } |
|
1005 |
|
1006 /// \brief Returns the flow on the edge. |
|
1007 /// |
|
1008 /// Sets the \c flowMap to the flow on the edges. This method can |
|
1009 /// be called after the second phase of algorithm. |
|
1010 Value flow(const Edge& edge) const { |
|
1011 return (*_flow)[edge]; |
|
1012 } |
|
1013 |
|
1014 /// @} |
|
1015 |
|
1016 }; |
|
1017 |
|
1018 } //namespace lemon |
|
1019 |
|
1020 #endif |