COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/goldberg_tarjan.h @ 2521:05c0ba99cc27

Last change on this file since 2521:05c0ba99cc27 was 2518:4c0a23bd70b5, checked in by Balazs Dezso, 16 years ago

Bugfix in min cut computation

File size: 27.1 KB
Line 
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
37namespace 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 = &map;
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 = &map;
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 = int((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 (!reached[n]) {
831          _level->markToBottom(n);
832        } else if ((*_excess)[n] > 0 && _target != n) {
833          _level->activate(n);
834        }
835      }
836
837      Node n;
838
839      while ((n = _level->highestActive()) != INVALID) {
840        Value excess = (*_excess)[n];
841        int level = _level->highestActiveLevel();
842        int new_level = _level->maxLevel();
843
844        if (_dt->findRoot(n) != n) {
845          if (sendIn(n, excess)) goto no_more_push;
846        }
847       
848        for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
849          Value rem = (*_capacity)[e] - (*_flow)[e];
850          Node v = _graph.target(e);
851         
852          if (!_tolerance.positive(rem) && (*_dt_edges)[v] != e) continue;
853
854          if ((*_level)[v] < level) {
855           
856            if (_dt->findSize(n) + _dt->findSize(v) <
857                _tree_bound * _max_tree_size) {
858              _dt->addCost(n, -_max_value);
859              _dt->addCost(n, rem);
860              _dt->link(n, v);
861              _dt_edges->set(n, e);
862              if (sendIn(n, excess)) goto no_more_push;
863            } else {
864              if (!_level->active(v) && v != _source) {
865                _level->activate(v);
866              }
867              if (!_tolerance.less(rem, excess)) {
868                _flow->set(e, (*_flow)[e] + excess);
869                _excess->set(v, (*_excess)[v] + excess);
870                excess = 0;               
871                goto no_more_push;
872              } else {
873                excess -= rem;
874                _excess->set(v, (*_excess)[v] + rem);
875                _flow->set(e, (*_capacity)[e]);
876              }         
877            }
878          } else if (new_level > (*_level)[v]) {
879            new_level = (*_level)[v];
880          }
881        }
882
883        for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
884          Value rem = (*_flow)[e];
885          Node v = _graph.source(e);
886          if (!_tolerance.positive(rem) && (*_dt_edges)[v] != e) continue;
887
888          if ((*_level)[v] < level) {
889           
890            if (_dt->findSize(n) + _dt->findSize(v) <
891                _tree_bound * _max_tree_size) {
892              _dt->addCost(n, - _max_value);
893              _dt->addCost(n, rem);
894              _dt->link(n, v);
895              _dt_edges->set(n, e);
896              if (sendIn(n, excess)) goto no_more_push;
897            } else {
898              if (!_level->active(v) && v != _source) {
899                _level->activate(v);
900              }
901              if (!_tolerance.less(rem, excess)) {
902                _flow->set(e, (*_flow)[e] - excess);
903                _excess->set(v, (*_excess)[v] + excess);
904                excess = 0;               
905                goto no_more_push;
906              } else {
907                excess -= rem;
908                _excess->set(v, (*_excess)[v] + rem);
909                _flow->set(e, 0);
910              }         
911            }
912          } else if (new_level > (*_level)[v]) {
913            new_level = (*_level)[v];
914          }
915        }
916               
917      no_more_push:
918
919        _excess->set(n, excess);
920       
921        if (excess != 0) {
922          cutChildren(n);
923          if (new_level + 1 < _level->maxLevel()) {
924            _level->liftHighestActive(new_level + 1);
925          } else {
926            _level->liftHighestActiveToTop();
927          }
928          if (_level->emptyLevel(level)) {
929            _level->liftToTop(level);
930          }
931        } else {
932          _level->deactivate(n);
933        }       
934      }
935      extractTrees();
936    }
937
938    /// \brief Runs the Goldberg-Tarjan algorithm. 
939    ///
940    /// Runs the Goldberg-Tarjan algorithm.
941    /// \note pf.run() is just a shortcut of the following code.
942    /// \code
943    ///   pf.init();
944    ///   pf.startFirstPhase();
945    ///   pf.startSecondPhase();
946    /// \endcode
947    void run() {
948      init();
949      startFirstPhase();
950      startSecondPhase();
951    }
952
953    /// \brief Runs the Goldberg-Tarjan algorithm to compute the minimum cut. 
954    ///
955    /// Runs the Goldberg-Tarjan algorithm to compute the minimum cut.
956    /// \note pf.runMinCut() is just a shortcut of the following code.
957    /// \code
958    ///   pf.init();
959    ///   pf.startFirstPhase();
960    /// \endcode
961    void runMinCut() {
962      init();
963      startFirstPhase();
964    }
965
966    /// @}
967
968    /// \name Query Functions
969    /// The result of the %Dijkstra algorithm can be obtained using these
970    /// functions.\n
971    /// Before the use of these functions,
972    /// either run() or start() must be called.
973   
974    ///@{
975
976    /// \brief Returns the value of the maximum flow.
977    ///
978    /// Returns the value of the maximum flow by returning the excess
979    /// of the target node \c t. This value equals to the value of
980    /// the maximum flow already after the first phase.
981    Value flowValue() const {
982      return (*_excess)[_target];
983    }
984
985    /// \brief Returns true when the node is on the source side of minimum cut.
986    ///
987    /// Returns true when the node is on the source side of minimum
988    /// cut. This method can be called both after running \ref
989    /// startFirstPhase() and \ref startSecondPhase().
990    bool minCut(const Node& node) const {
991      return ((*_level)[node] == _level->maxLevel()) == _phase;
992    }
993 
994    /// \brief Returns a minimum value cut.
995    ///
996    /// Sets the \c cutMap to the characteristic vector of a minimum value
997    /// cut. This method can be called both after running \ref
998    /// startFirstPhase() and \ref startSecondPhase(). The result after second
999    /// phase could be changed slightly if inexact computation is used.
1000    /// \pre The \c cutMap should be a bool-valued node-map.
1001    template <typename CutMap>
1002    void minCutMap(CutMap& cutMap) const {
1003      for (NodeIt n(_graph); n != INVALID; ++n) {
1004        cutMap.set(n, minCut(n));
1005      }
1006    }
1007
1008    /// \brief Returns the flow on the edge.
1009    ///
1010    /// Sets the \c flowMap to the flow on the edges. This method can
1011    /// be called after the second phase of algorithm.
1012    Value flow(const Edge& edge) const {
1013      return (*_flow)[edge];
1014    }
1015
1016    /// @}
1017
1018  };
1019 
1020} //namespace lemon
1021
1022#endif
Note: See TracBrowser for help on using the repository browser.