lemon/circulation.h
changeset 2526 b7727edd44f2
parent 2512 371cf309fc3c
child 2527 10f3b3286e63
equal deleted inserted replaced
6:c486c14da1c0 7:60a92dd4c722
    29 ///\file
    29 ///\file
    30 ///\brief Push-prelabel algorithm for finding a feasible circulation.
    30 ///\brief Push-prelabel algorithm for finding a feasible circulation.
    31 ///
    31 ///
    32 namespace lemon {
    32 namespace lemon {
    33 
    33 
    34   ///Preflow algorithm for the Network Circulation Problem.
    34   /// \brief Default traits class of Circulation class.
       
    35   ///
       
    36   /// Default traits class of Circulation class.
       
    37   /// \param _Graph Graph type.
       
    38   /// \param _CapacityMap Type of capacity map.
       
    39   template <typename _Graph, typename _LCapMap, 
       
    40 	    typename _UCapMap, typename _DeltaMap>
       
    41   struct CirculationDefaultTraits {
       
    42 
       
    43     /// \brief The graph type the algorithm runs on. 
       
    44     typedef _Graph Graph;
       
    45 
       
    46     /// \brief The type of the map that stores the circulation lower
       
    47     /// bound.
       
    48     ///
       
    49     /// The type of the map that stores the circulation lower bound.
       
    50     /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
       
    51     typedef _LCapMap LCapMap;
       
    52 
       
    53     /// \brief The type of the map that stores the circulation upper
       
    54     /// bound.
       
    55     ///
       
    56     /// The type of the map that stores the circulation upper bound.
       
    57     /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
       
    58     typedef _UCapMap UCapMap;
       
    59 
       
    60     /// \brief The type of the map that stores the upper bound of
       
    61     /// node excess.
       
    62     ///
       
    63     /// The type of the map that stores the lower bound of node
       
    64     /// excess. It must meet the \ref concepts::ReadMap "ReadMap"
       
    65     /// concept.
       
    66     typedef _DeltaMap DeltaMap;
       
    67 
       
    68     /// \brief The type of the length of the edges.
       
    69     typedef typename DeltaMap::Value Value;
       
    70 
       
    71     /// \brief The map type that stores the flow values.
       
    72     ///
       
    73     /// The map type that stores the flow values. 
       
    74     /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
       
    75     typedef typename Graph::template EdgeMap<Value> FlowMap;
       
    76 
       
    77     /// \brief Instantiates a FlowMap.
       
    78     ///
       
    79     /// This function instantiates a \ref FlowMap. 
       
    80     /// \param graph The graph, to which we would like to define the flow map.
       
    81     static FlowMap* createFlowMap(const Graph& graph) {
       
    82       return new FlowMap(graph);
       
    83     }
       
    84 
       
    85     /// \brief The eleavator type used by Circulation algorithm.
       
    86     /// 
       
    87     /// The elevator type used by Circulation algorithm.
       
    88     ///
       
    89     /// \sa Elevator
       
    90     /// \sa LinkedElevator
       
    91     typedef Elevator<Graph, typename Graph::Node> Elevator;
       
    92     
       
    93     /// \brief Instantiates an Elevator.
       
    94     ///
       
    95     /// This function instantiates a \ref Elevator. 
       
    96     /// \param graph The graph, to which we would like to define the elevator.
       
    97     /// \param max_level The maximum level of the elevator.
       
    98     static Elevator* createElevator(const Graph& graph, int max_level) {
       
    99       return new Elevator(graph, max_level);
       
   100     }
       
   101 
       
   102     /// \brief The tolerance used by the algorithm
       
   103     ///
       
   104     /// The tolerance used by the algorithm to handle inexact computation.
       
   105     typedef Tolerance<Value> Tolerance;
       
   106 
       
   107   };
       
   108   
       
   109   ///Push-relabel algorithm for the Network Circulation Problem.
    35   
   110   
    36   ///\ingroup max_flow
   111   ///\ingroup max_flow
    37   ///This class implements a preflow algorithm
   112   ///This class implements a push-relabel algorithm
    38   ///for the Network Circulation Problem.
   113   ///for the Network Circulation Problem.
    39   ///The exact formulation of this problem is the following.
   114   ///The exact formulation of this problem is the following.
    40   /// \f[\sum_{e\in\rho(v)}x(e)-\sum_{e\in\delta(v)}x(e)\leq -delta(v)\quad \forall v\in V \f]
   115   /// \f[\sum_{e\in\rho(v)}x(e)-\sum_{e\in\delta(v)}x(e)\leq -delta(v)\quad \forall v\in V \f]
    41   /// \f[ lo(e)\leq x(e) \leq up(e) \quad \forall e\in E \f]
   116   /// \f[ lo(e)\leq x(e) \leq up(e) \quad \forall e\in E \f]
    42   ///
   117   ///
    43   template<class Graph,
   118   template<class _Graph,
    44 	   class Value,
   119 	   class _LCapMap=typename _Graph::template EdgeMap<int>,
    45 	   class FlowMap=typename Graph::template EdgeMap<Value>,
   120 	   class _UCapMap=_LCapMap,
    46 	   class LCapMap=typename Graph::template EdgeMap<Value>,
   121 	   class _DeltaMap=typename _Graph::template NodeMap<
    47 	   class UCapMap=LCapMap,
   122 	     typename _UCapMap::Value>,
    48 	   class DeltaMap=typename Graph::template NodeMap<Value>
   123 	   class _Traits=CirculationDefaultTraits<_Graph, _LCapMap, 
    49 	    >
   124 						  _UCapMap, _DeltaMap> >
    50   class Circulation {
   125   class Circulation {
    51     typedef typename Graph::Node Node;
   126 
    52     typedef typename Graph::NodeIt NodeIt;
   127     typedef _Traits Traits;
    53     typedef typename Graph::Edge Edge;
   128     typedef typename Traits::Graph Graph;
    54     typedef typename Graph::EdgeIt EdgeIt;
   129     GRAPH_TYPEDEFS(typename Graph);
    55     typedef typename Graph::InEdgeIt InEdgeIt;
   130 
    56     typedef typename Graph::OutEdgeIt OutEdgeIt;
   131     typedef typename Traits::Value Value;
    57     
   132 
       
   133     typedef typename Traits::LCapMap LCapMap;
       
   134     typedef typename Traits::UCapMap UCapMap;
       
   135     typedef typename Traits::DeltaMap DeltaMap;
       
   136     typedef typename Traits::FlowMap FlowMap;
       
   137     typedef typename Traits::Elevator Elevator;
       
   138     typedef typename Traits::Tolerance Tolerance;
       
   139 
       
   140     typedef typename Graph::template NodeMap<Value> ExcessMap;
    58 
   141 
    59     const Graph &_g;
   142     const Graph &_g;
    60     int _node_num;
   143     int _node_num;
    61 
   144 
    62     const LCapMap &_lo;
   145     const LCapMap *_lo;
    63     const UCapMap &_up;
   146     const UCapMap *_up;
    64     const DeltaMap &_delta;
   147     const DeltaMap *_delta;
    65     FlowMap &_x;
   148 
    66     Tolerance<Value> _tol;
   149     FlowMap *_flow;
    67     Elevator<Graph,typename Graph::Node> _levels;
   150     bool _local_flow;
    68     typename Graph::template NodeMap<Value> _excess;
   151 
       
   152     Elevator* _level;
       
   153     bool _local_level;
       
   154 
       
   155     ExcessMap* _excess;
       
   156 
       
   157     Tolerance _tol;
       
   158     int _el;
    69 
   159 
    70   public:
   160   public:
    71     ///\e
   161 
    72     Circulation(const Graph &g,const LCapMap &lo,const UCapMap &up,
   162     typedef Circulation Create;
    73 		const DeltaMap &delta,FlowMap &x) :
   163 
    74       _g(g),
   164     ///\name Named template parameters
    75       _node_num(countNodes(g)),
   165 
    76       _lo(lo),_up(up),_delta(delta),_x(x),
   166     ///@{
    77       _levels(g,_node_num),
   167 
    78       _excess(g)
   168     template <typename _FlowMap>
    79     {
   169     struct DefFlowMapTraits : public Traits {
    80     }
   170       typedef _FlowMap FlowMap;
    81     
   171       static FlowMap *createFlowMap(const Graph&) {
       
   172 	throw UninitializedParameter();
       
   173       }
       
   174     };
       
   175 
       
   176     /// \brief \ref named-templ-param "Named parameter" for setting
       
   177     /// FlowMap type
       
   178     ///
       
   179     /// \ref named-templ-param "Named parameter" for setting FlowMap
       
   180     /// type
       
   181     template <typename _FlowMap>
       
   182     struct DefFlowMap 
       
   183       : public Circulation<Graph, LCapMap, UCapMap, DeltaMap, 
       
   184 			   DefFlowMapTraits<_FlowMap> > {
       
   185       typedef Circulation<Graph, LCapMap, UCapMap, DeltaMap, 
       
   186 			  DefFlowMapTraits<_FlowMap> > Create;
       
   187     };
       
   188 
       
   189     template <typename _Elevator>
       
   190     struct DefElevatorTraits : public Traits {
       
   191       typedef _Elevator Elevator;
       
   192       static Elevator *createElevator(const Graph&, int) {
       
   193 	throw UninitializedParameter();
       
   194       }
       
   195     };
       
   196 
       
   197     /// \brief \ref named-templ-param "Named parameter" for setting
       
   198     /// Elevator type
       
   199     ///
       
   200     /// \ref named-templ-param "Named parameter" for setting Elevator
       
   201     /// type
       
   202     template <typename _Elevator>
       
   203     struct DefElevator 
       
   204       : public Circulation<Graph, LCapMap, UCapMap, DeltaMap, 
       
   205 			   DefElevatorTraits<_Elevator> > {
       
   206       typedef Circulation<Graph, LCapMap, UCapMap, DeltaMap,
       
   207 			  DefElevatorTraits<_Elevator> > Create;
       
   208     };
       
   209 
       
   210     template <typename _Elevator>
       
   211     struct DefStandardElevatorTraits : public Traits {
       
   212       typedef _Elevator Elevator;
       
   213       static Elevator *createElevator(const Graph& graph, int max_level) {
       
   214 	return new Elevator(graph, max_level);
       
   215       }
       
   216     };
       
   217 
       
   218     /// \brief \ref named-templ-param "Named parameter" for setting
       
   219     /// Elevator type
       
   220     ///
       
   221     /// \ref named-templ-param "Named parameter" for setting Elevator
       
   222     /// type. The Elevator should be standard constructor interface, ie.
       
   223     /// the graph and the maximum level should be passed to it.
       
   224     template <typename _Elevator>
       
   225     struct DefStandardElevator 
       
   226       : public Circulation<Graph, LCapMap, UCapMap, DeltaMap, 
       
   227 		       DefStandardElevatorTraits<_Elevator> > {
       
   228       typedef Circulation<Graph, LCapMap, UCapMap, DeltaMap,
       
   229 		      DefStandardElevatorTraits<_Elevator> > Create;
       
   230     };    
       
   231 
       
   232     /// @}
       
   233 
       
   234     /// The constructor of the class.
       
   235 
       
   236     /// The constructor of the class. 
       
   237     /// \param g The directed graph the algorithm runs on. 
       
   238     /// \param lo The lower bound capacity of the edges. 
       
   239     /// \param up The upper bound capacity of the edges.
       
   240     /// \param delta The lower bound on node excess.
       
   241     Circulation(const Graph &g,const LCapMap &lo,
       
   242 		const UCapMap &up,const DeltaMap &delta) 
       
   243       : _g(g), _node_num(),
       
   244 	_lo(&lo),_up(&up),_delta(&delta),_flow(0),_local_flow(false),
       
   245 	_level(0), _local_level(false), _excess(0), _el() {}
       
   246 
       
   247     /// Destrcutor.
       
   248     ~Circulation() {
       
   249       destroyStructures();
       
   250     }
       
   251 
    82   private:
   252   private:
    83 
   253 
    84     void addExcess(Node n,Value v)
   254     void createStructures() {
    85     {
   255       _node_num = _el = countNodes(_g);
    86       if(_tol.positive(_excess[n]+=v))
   256 
    87 	{
   257       if (!_flow) {
    88 	  if(!_levels.active(n)) _levels.activate(n);
   258 	_flow = Traits::createFlowMap(_g);
    89 	}
   259 	_local_flow = true;
    90       else if(_levels.active(n)) _levels.deactivate(n);
   260       }
    91     }
   261       if (!_level) {
    92     
   262 	_level = Traits::createElevator(_g, _node_num);
       
   263 	_local_level = true;
       
   264       }
       
   265       if (!_excess) {
       
   266 	_excess = new ExcessMap(_g);
       
   267       }
       
   268     }
       
   269 
       
   270     void destroyStructures() {
       
   271       if (_local_flow) {
       
   272 	delete _flow;
       
   273       }
       
   274       if (_local_level) {
       
   275 	delete _level;
       
   276       }
       
   277       if (_excess) {
       
   278 	delete _excess;
       
   279       }
       
   280     }
       
   281 
       
   282   public:
       
   283 
       
   284     /// Sets the lower bound capacity map.
       
   285 
       
   286     /// Sets the lower bound capacity map.
       
   287     /// \return \c (*this)
       
   288     Circulation& lowerCapMap(const LCapMap& map) {
       
   289       _lo = &map;
       
   290       return *this;
       
   291     }
       
   292 
       
   293     /// Sets the upper bound capacity map.
       
   294 
       
   295     /// Sets the upper bound capacity map.
       
   296     /// \return \c (*this)
       
   297     Circulation& upperCapMap(const LCapMap& map) {
       
   298       _up = &map;
       
   299       return *this;
       
   300     }
       
   301 
       
   302     /// Sets the lower bound map on excess.
       
   303 
       
   304     /// Sets the lower bound map on excess.
       
   305     /// \return \c (*this)
       
   306     Circulation& deltaMap(const DeltaMap& map) {
       
   307       _delta = &map;
       
   308       return *this;
       
   309     }
       
   310 
       
   311     /// Sets the flow map.
       
   312 
       
   313     /// Sets the flow map.
       
   314     /// \return \c (*this)
       
   315     Circulation& flowMap(FlowMap& map) {
       
   316       if (_local_flow) {
       
   317 	delete _flow;
       
   318 	_local_flow = false;
       
   319       }
       
   320       _flow = &map;
       
   321       return *this;
       
   322     }
       
   323 
       
   324     /// Returns the flow map.
       
   325 
       
   326     /// \return The flow map.
       
   327     ///
       
   328     const FlowMap& flowMap() {
       
   329       return *_flow;
       
   330     }
       
   331 
       
   332     /// Sets the elevator.
       
   333 
       
   334     /// Sets the elevator.
       
   335     /// \return \c (*this)
       
   336     Circulation& elevator(Elevator& elevator) {
       
   337       if (_local_level) {
       
   338 	delete _level;
       
   339 	_local_level = false;
       
   340       }
       
   341       _level = &elevator;
       
   342       return *this;
       
   343     }
       
   344 
       
   345     /// Returns the elevator.
       
   346 
       
   347     /// \return The elevator.
       
   348     ///
       
   349     const Elevator& elevator() {
       
   350       return *_level;
       
   351     }
       
   352     
       
   353     /// Sets the tolerance used by algorithm.
       
   354 
       
   355     /// Sets the tolerance used by algorithm.
       
   356     ///
       
   357     Circulation& tolerance(const Tolerance& tolerance) const {
       
   358       _tol = tolerance;
       
   359       return *this;
       
   360     } 
       
   361 
       
   362     /// Returns the tolerance used by algorithm.
       
   363 
       
   364     /// Returns the tolerance used by algorithm.
       
   365     ///
       
   366     const Tolerance& tolerance() const {
       
   367       return tolerance;
       
   368     } 
       
   369     
       
   370     /// \name Execution control The simplest way to execute the
       
   371     /// algorithm is to use one of the member functions called \c
       
   372     /// run().  
       
   373     /// \n 
       
   374     /// If you need more control on initial solution or execution then
       
   375     /// you have to call one \ref init() function and then the start()
       
   376     /// function.
       
   377     
       
   378     ///@{
       
   379   
       
   380     /// Initializes the internal data structures.
       
   381 
       
   382     /// Initializes the internal data structures. This function sets
       
   383     /// all flow values to the lower bound.  
       
   384     /// \return This function returns false if the initialization
       
   385     /// process found a barrier.
    93     void init() 
   386     void init() 
    94     {
   387     {
       
   388       createStructures();
       
   389 
       
   390       for(NodeIt n(_g);n!=INVALID;++n) {
       
   391 	_excess->set(n, (*_delta)[n]);
       
   392       }
    95      
   393      
    96       _x=_lo;
   394       for (EdgeIt e(_g);e!=INVALID;++e) {
    97 
   395 	_flow->set(e, (*_lo)[e]);
    98       for(NodeIt n(_g);n!=INVALID;++n) _excess[n]=_delta[n];
   396 	_excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_flow)[e]);
    99 
   397 	_excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_flow)[e]);
       
   398       }
       
   399 
       
   400       typename Graph::template NodeMap<bool> reached(_g, false);
       
   401 
       
   402 
       
   403       // global relabeling tested, but in general case it provides
       
   404       // worse performance for random graphs
       
   405       _level->initStart();
       
   406       for(NodeIt n(_g);n!=INVALID;++n)
       
   407 	_level->initAddItem(n);
       
   408       _level->initFinish();
       
   409       for(NodeIt n(_g);n!=INVALID;++n)
       
   410 	if(_tol.positive((*_excess)[n]))
       
   411 	  _level->activate(n);
       
   412     }
       
   413 
       
   414     /// Initializes the internal data structures.
       
   415 
       
   416     /// Initializes the internal data structures. This functions uses
       
   417     /// greedy approach to construct the initial solution. 
       
   418     void greedyInit() 
       
   419     {
       
   420       createStructures();
       
   421      
       
   422       for(NodeIt n(_g);n!=INVALID;++n) {
       
   423 	_excess->set(n, (*_delta)[n]);
       
   424       }
       
   425      
       
   426       for (EdgeIt e(_g);e!=INVALID;++e) {
       
   427 	if (!_tol.positive((*_excess)[_g.target(e)] + (*_up)[e])) {
       
   428 	  _flow->set(e, (*_up)[e]);
       
   429 	  _excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_up)[e]);
       
   430 	  _excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_up)[e]);
       
   431 	} else if (_tol.positive((*_excess)[_g.target(e)] + (*_lo)[e])) {
       
   432 	  _flow->set(e, (*_lo)[e]);
       
   433 	  _excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_up)[e]);
       
   434 	  _excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_up)[e]);
       
   435 	} else {
       
   436 	  Value fc = -(*_excess)[_g.target(e)];
       
   437 	  _flow->set(e, fc);
       
   438 	  _excess->set(_g.target(e), 0);
       
   439 	  _excess->set(_g.source(e), (*_excess)[_g.source(e)] - fc);
       
   440 	}
       
   441       }
       
   442      
       
   443       _level->initStart();
       
   444       for(NodeIt n(_g);n!=INVALID;++n)
       
   445 	_level->initAddItem(n);
       
   446       _level->initFinish();
       
   447       for(NodeIt n(_g);n!=INVALID;++n)
       
   448 	if(_tol.positive((*_excess)[n]))
       
   449 	  _level->activate(n);
       
   450     }
       
   451 
       
   452     ///Starts the algorithm
       
   453 
       
   454     ///This function starts the algorithm.
       
   455     ///\return This function returns true if it found a feasible circulation.
       
   456     ///
       
   457     ///\sa barrier()
       
   458     bool start() 
       
   459     {
       
   460       
       
   461       Node act;
       
   462       Node bact=INVALID;
       
   463       Node last_activated=INVALID;
       
   464       while((act=_level->highestActive())!=INVALID) {
       
   465 	int actlevel=(*_level)[act];
       
   466 	int mlevel=_node_num;
       
   467 	Value exc=(*_excess)[act];
       
   468 	
       
   469 	for(OutEdgeIt e(_g,act);e!=INVALID; ++e) {
       
   470 	  Node v = _g.target(e);
       
   471 	  Value fc=(*_up)[e]-(*_flow)[e];
       
   472 	  if(!_tol.positive(fc)) continue;
       
   473 	  if((*_level)[v]<actlevel) {
       
   474 	    if(!_tol.less(fc, exc)) {
       
   475 	      _flow->set(e, (*_flow)[e] + exc);
       
   476 	      _excess->set(v, (*_excess)[v] + exc);
       
   477 	      if(!_level->active(v) && _tol.positive((*_excess)[v]))
       
   478 		_level->activate(v);
       
   479 	      _excess->set(act,0);
       
   480 	      _level->deactivate(act);
       
   481 	      goto next_l;
       
   482 	    }
       
   483 	    else {
       
   484 	      _flow->set(e, (*_up)[e]);
       
   485 	      _excess->set(v, (*_excess)[v] + exc);
       
   486 	      if(!_level->active(v) && _tol.positive((*_excess)[v]))
       
   487 		_level->activate(v);
       
   488 	      exc-=fc;
       
   489 	    }
       
   490 	  } 
       
   491 	  else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
       
   492 	}
       
   493 	for(InEdgeIt e(_g,act);e!=INVALID; ++e) {
       
   494 	  Node v = _g.source(e);
       
   495 	  Value fc=(*_flow)[e]-(*_lo)[e];
       
   496 	  if(!_tol.positive(fc)) continue;
       
   497 	  if((*_level)[v]<actlevel) {
       
   498 	    if(!_tol.less(fc, exc)) {
       
   499 	      _flow->set(e, (*_flow)[e] - exc);
       
   500 	      _excess->set(v, (*_excess)[v] + exc);
       
   501 	      if(!_level->active(v) && _tol.positive((*_excess)[v]))
       
   502 		_level->activate(v);
       
   503 	      _excess->set(act,0);
       
   504 	      _level->deactivate(act);
       
   505 	      goto next_l;
       
   506 	    }
       
   507 	    else {
       
   508 	      _flow->set(e, (*_lo)[e]);
       
   509 	      _excess->set(v, (*_excess)[v] + fc);
       
   510 	      if(!_level->active(v) && _tol.positive((*_excess)[v]))
       
   511 		_level->activate(v);
       
   512 	      exc-=fc;
       
   513 	    }
       
   514 	  } 
       
   515 	  else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
       
   516 	}
       
   517    
       
   518 	_excess->set(act, exc);
       
   519 	if(!_tol.positive(exc)) _level->deactivate(act);
       
   520 	else if(mlevel==_node_num) {
       
   521 	  _level->liftHighestActiveToTop();
       
   522 	  _el = _node_num;
       
   523 	  return false;
       
   524 	}
       
   525 	else {
       
   526 	  _level->liftHighestActive(mlevel+1);
       
   527 	  if(_level->onLevel(actlevel)==0) {
       
   528 	    _el = actlevel;
       
   529 	    return false;
       
   530 	  }
       
   531 	}
       
   532       next_l:
       
   533 	;
       
   534       }
       
   535       return true;
       
   536     }
       
   537 
       
   538     /// Runs the circulation algorithm.  
       
   539 
       
   540     /// Runs the circulation algorithm.
       
   541     /// \note fc.run() is just a shortcut of the following code.
       
   542     /// \code
       
   543     ///   fc.greedyInit();
       
   544     ///   return fc.start();
       
   545     /// \endcode
       
   546     bool run() {
       
   547       greedyInit();
       
   548       return start();
       
   549     }
       
   550 
       
   551     /// @}
       
   552 
       
   553     /// \name Query Functions
       
   554     /// The result of the %Circulation algorithm can be obtained using
       
   555     /// these functions.
       
   556     /// \n
       
   557     /// Before the use of these functions,
       
   558     /// either run() or start() must be called.
       
   559     
       
   560     ///@{
       
   561     
       
   562     ///Returns a barrier
       
   563     
       
   564     ///Barrier is a set \e B of nodes for which
       
   565     /// \f[ \sum_{v\in B}-delta(v)<\sum_{e\in\rho(B)}lo(e)-\sum_{e\in\delta(B)}up(e) \f]
       
   566     ///holds. The existence of a set with this property prooves that a feasible
       
   567     ///flow cannot exists.
       
   568     ///\sa checkBarrier()
       
   569     ///\sa run()
       
   570     template<class GT>
       
   571     void barrierMap(GT &bar) 
       
   572     {
       
   573       for(NodeIt n(_g);n!=INVALID;++n)
       
   574 	bar.set(n, (*_level)[n] >= _el);
       
   575     }  
       
   576 
       
   577     ///Returns true if the node is in the barrier
       
   578 
       
   579     ///Returns true if the node is in the barrier
       
   580     ///\sa barrierMap()
       
   581     bool barrier(const Node& node) 
       
   582     {
       
   583       return (*_level)[node] >= _el;
       
   584     }  
       
   585 
       
   586     /// \brief Returns the flow on the edge.
       
   587     ///
       
   588     /// Sets the \c flowMap to the flow on the edges. This method can
       
   589     /// be called after the second phase of algorithm.
       
   590     Value flow(const Edge& edge) const {
       
   591       return (*_flow)[edge];
       
   592     }
       
   593 
       
   594     /// @}
       
   595 
       
   596     /// \name Checker Functions
       
   597     /// The feasibility  of the results can be checked using
       
   598     /// these functions.
       
   599     /// \n
       
   600     /// Before the use of these functions,
       
   601     /// either run() or start() must be called.
       
   602     
       
   603     ///@{
       
   604 
       
   605     ///Check if the  \c flow is a feasible circulation
       
   606     bool checkFlow() {
   100       for(EdgeIt e(_g);e!=INVALID;++e)
   607       for(EdgeIt e(_g);e!=INVALID;++e)
   101 	{
   608 	if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
   102 	  _excess[_g.target(e)]+=_x[e];
       
   103 	  _excess[_g.source(e)]-=_x[e];
       
   104 	}
       
   105      
       
   106       _levels.initStart();
       
   107       for(NodeIt n(_g);n!=INVALID;++n)
       
   108 	_levels.initAddItem(n);
       
   109       _levels.initFinish();
       
   110       for(NodeIt n(_g);n!=INVALID;++n)
       
   111 	if(_tol.positive(_excess[n]))
       
   112 	  _levels.activate(n);
       
   113     }
       
   114 
       
   115   public:
       
   116     ///Check if \c x is a feasible circulation
       
   117     template<class FT>
       
   118     bool checkX(FT &x) {
       
   119       for(EdgeIt e(_g);e!=INVALID;++e)
       
   120 	if(x[e]<_lo[e]||x[e]>_up[e]) return false;
       
   121       for(NodeIt n(_g);n!=INVALID;++n)
   609       for(NodeIt n(_g);n!=INVALID;++n)
   122 	{
   610 	{
   123 	  Value dif=-_delta[n];
   611 	  Value dif=-(*_delta)[n];
   124 	  for(InEdgeIt e(_g,n);e!=INVALID;++e) dif-=x[e];
   612 	  for(InEdgeIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
   125 	  for(OutEdgeIt e(_g,n);e!=INVALID;++e) dif+=x[e];
   613 	  for(OutEdgeIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
   126 	  if(_tol.negative(dif)) return false;
   614 	  if(_tol.negative(dif)) return false;
   127 	}
   615 	}
   128       return true;
   616       return true;
   129     };
   617     }
   130     ///Check if the default \c x is a feasible circulation
   618 
   131     bool checkX() { return checkX(_x); }
   619     ///Check whether or not the last execution provides a barrier
   132 
   620 
   133     ///Check if \c bar is a real barrier
   621     ///Check whether or not the last execution provides a barrier
   134 
       
   135     ///Check if \c bar is a real barrier
       
   136     ///\sa barrier()
   622     ///\sa barrier()
   137     template<class GT>
   623     bool checkBarrier() 
   138     bool checkBarrier(GT &bar) 
       
   139     {
   624     {
   140       Value delta=0;
   625       Value delta=0;
   141       for(NodeIt n(_g);n!=INVALID;++n)
   626       for(NodeIt n(_g);n!=INVALID;++n)
   142 	if(bar[n])
   627 	if(barrier(n))
   143 	  delta-=_delta[n];
   628 	  delta-=(*_delta)[n];
   144       for(EdgeIt e(_g);e!=INVALID;++e)
   629       for(EdgeIt e(_g);e!=INVALID;++e)
   145 	{
   630 	{
   146 	  Node s=_g.source(e);
   631 	  Node s=_g.source(e);
   147 	  Node t=_g.target(e);
   632 	  Node t=_g.target(e);
   148 	  if(bar[s]&&!bar[t]) delta+=_up[e];
   633 	  if(barrier(s)&&!barrier(t)) delta+=(*_up)[e];
   149 	  else if(bar[t]&&!bar[s]) delta-=_lo[e];
   634 	  else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
   150 	}
   635 	}
   151       return _tol.negative(delta);
   636       return _tol.negative(delta);
   152     }  
   637     }
   153     ///Check whether or not the last execution provides a barrier
   638 
   154 
   639     /// @}
   155     ///Check whether or not the last execution provides a barrier
       
   156     ///\sa barrier()
       
   157     bool checkBarrier() 
       
   158     {
       
   159       typename Graph:: template NodeMap<bool> bar(_g);
       
   160       barrier(bar);
       
   161       return checkBarrier(bar);
       
   162     }
       
   163     ///Run the algorithm
       
   164 
       
   165     ///This function runs the algorithm.
       
   166     ///\return This function returns -1 if it found a feasible circulation.
       
   167     /// nonnegative values (including 0) mean that no feasible solution is
       
   168     /// found. In this case the return value means an "empty level".
       
   169     ///
       
   170     ///\sa barrier()
       
   171     int run() 
       
   172     {
       
   173       init();
       
   174       
       
   175 #ifdef LEMON_CIRCULATION_DEBUG
       
   176       for(NodeIt n(_g);n!=INVALID;++n)
       
   177 	std::cerr<< _levels[n] << ' ';
       
   178       std::cerr << std::endl;
       
   179 #endif      
       
   180       Node act;
       
   181       Node bact=INVALID;
       
   182       Node last_activated=INVALID;
       
   183       while((act=_levels.highestActive())!=INVALID) {
       
   184 	int actlevel=_levels[act];
       
   185 	int tlevel;
       
   186 	int mlevel=_node_num;
       
   187 	Value exc=_excess[act];
       
   188 	Value fc;
       
   189 	
       
   190 #ifdef LEMON_CIRCULATION_DEBUG
       
   191 	for(NodeIt n(_g);n!=INVALID;++n)
       
   192 	  std::cerr<< _levels[n] << ' ';
       
   193 	std::cerr << std::endl;
       
   194 	std::cerr << "Process node " << _g.id(act)
       
   195 		  << " on level " << actlevel
       
   196 		  << " with excess " << exc
       
   197 		  << std::endl;
       
   198 #endif
       
   199 	for(OutEdgeIt e(_g,act);e!=INVALID; ++e)
       
   200 	  if((fc=_up[e]-_x[e])>0)
       
   201 	    if((tlevel=_levels[_g.target(e)])<actlevel)
       
   202 	      if(fc<=exc) {
       
   203 		_x[e]=_up[e];
       
   204 		addExcess(_g.target(e),fc);
       
   205 		exc-=fc;
       
   206 #ifdef LEMON_CIRCULATION_DEBUG
       
   207 		std::cerr << "  Push " << fc
       
   208 			  << " toward " << _g.id(_g.target(e)) << std::endl;
       
   209 #endif
       
   210 	      }
       
   211 	      else {
       
   212 		_x[e]+=exc;
       
   213 		addExcess(_g.target(e),exc);
       
   214 		//exc=0;
       
   215 		_excess[act]=0;
       
   216 		_levels.deactivate(act);
       
   217 #ifdef LEMON_CIRCULATION_DEBUG
       
   218 		std::cerr << "  Push " << exc
       
   219 			  << " toward " << _g.id(_g.target(e)) << std::endl;
       
   220 		std::cerr << "  Deactivate\n";
       
   221 #endif
       
   222 		goto next_l;
       
   223 	      }
       
   224 	    else if(tlevel<mlevel) mlevel=tlevel;
       
   225 	
       
   226 	for(InEdgeIt e(_g,act);e!=INVALID; ++e)
       
   227 	  if((fc=_x[e]-_lo[e])>0)
       
   228 	    if((tlevel=_levels[_g.source(e)])<actlevel)
       
   229 	      if(fc<=exc) {
       
   230 		_x[e]=_lo[e];
       
   231 		addExcess(_g.source(e),fc);
       
   232 		exc-=fc;
       
   233 #ifdef LEMON_CIRCULATION_DEBUG
       
   234 		std::cerr << "  Push " << fc
       
   235 			  << " toward " << _g.id(_g.source(e)) << std::endl;
       
   236 #endif
       
   237 	      }
       
   238 	      else {
       
   239 		_x[e]-=exc;
       
   240 		addExcess(_g.source(e),exc);
       
   241 		//exc=0;
       
   242 		_excess[act]=0;
       
   243 		_levels.deactivate(act);
       
   244 #ifdef LEMON_CIRCULATION_DEBUG
       
   245 		std::cerr << "  Push " << exc
       
   246 			  << " toward " << _g.id(_g.source(e)) << std::endl;
       
   247 		std::cerr << "  Deactivate\n";
       
   248 #endif
       
   249 		goto next_l;
       
   250               }
       
   251 	    else if(tlevel<mlevel) mlevel=tlevel;
       
   252    
       
   253 	_excess[act]=exc;
       
   254 	if(!_tol.positive(exc)) _levels.deactivate(act);
       
   255 	else if(mlevel==_node_num) {
       
   256 	  _levels.liftHighestActiveToTop();
       
   257 #ifdef LEMON_CIRCULATION_DEBUG
       
   258 	  std::cerr << "  Lift to level " << _node_num << std::endl;
       
   259 #endif
       
   260 	  return _levels.onLevel(_node_num-1)==0?_node_num-1:actlevel;
       
   261 	}
       
   262 	else {
       
   263 	  _levels.liftHighestActive(mlevel+1);
       
   264 #ifdef LEMON_CIRCULATION_DEBUG
       
   265 	  std::cerr << "  Lift to level " << mlevel+1 << std::endl;
       
   266 #endif
       
   267 	  if(_levels.onLevel(actlevel)==0)
       
   268 	    return actlevel;
       
   269 	}
       
   270       next_l:
       
   271 	;
       
   272       }
       
   273 #ifdef LEMON_CIRCULATION_DEBUG
       
   274       std::cerr << "Feasible flow found.\n";
       
   275 #endif
       
   276       return -1;
       
   277     }
       
   278     
       
   279     ///Return a barrier
       
   280     
       
   281     ///Barrier is a set \e B of nodes for which
       
   282     /// \f[ \sum_{v\in B}-delta(v)<\sum_{e\in\rho(B)}lo(e)-\sum_{e\in\delta(B)}up(e) \f]
       
   283     ///holds. The existence of a set with this property prooves that a feasible
       
   284     ///flow cannot exists.
       
   285     ///\pre The run() must have been executed, and its return value was -1.
       
   286     ///\sa checkBarrier()
       
   287     ///\sa run()
       
   288     template<class GT>
       
   289     void barrier(GT &bar,int empty_level=-1) 
       
   290     {
       
   291       if(empty_level==-1)
       
   292 	for(empty_level=0;_levels.onLevel(empty_level);empty_level++) ;
       
   293       for(NodeIt n(_g);n!=INVALID;++n)
       
   294 	bar[n] = _levels[n]>empty_level;
       
   295     }  
       
   296 
   640 
   297   };
   641   };
   298   
   642   
   299 }
   643 }
   300 
   644