lemon/preflow.h
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
changeset 1823 cb082cdf3667
parent 1786 a263c131e999
child 1835 eb6c34c76501
permissions -rw-r--r--
NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
     1 /* -*- C++ -*-
     2  * lemon/preflow.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_PREFLOW_H
    18 #define LEMON_PREFLOW_H
    19 
    20 #include <vector>
    21 #include <queue>
    22 
    23 #include <lemon/error.h>
    24 #include <lemon/invalid.h>
    25 #include <lemon/maps.h>
    26 #include <lemon/graph_utils.h>
    27 
    28 /// \file
    29 /// \ingroup flowalgs
    30 /// \brief Implementation of the preflow algorithm.
    31 
    32 namespace lemon {
    33 
    34   ///\ingroup flowalgs
    35   ///\brief %Preflow algorithms class.
    36   ///
    37   ///This class provides an implementation of the \e preflow \e
    38   ///algorithm producing a flow of maximum value in a directed
    39   ///graph. The preflow algorithms are the fastest known max flow algorithms
    40   ///up to now. The \e source node, the \e target node, the \e
    41   ///capacity of the edges and the \e starting \e flow value of the
    42   ///edges should be passed to the algorithm through the
    43   ///constructor. It is possible to change these quantities using the
    44   ///functions \ref source, \ref target, \ref capacityMap and \ref
    45   ///flowMap.
    46   ///
    47   ///After running \ref lemon::Preflow::phase1() "phase1()"
    48   ///or \ref lemon::Preflow::run() "run()", the maximal flow
    49   ///value can be obtained by calling \ref flowValue(). The minimum
    50   ///value cut can be written into a <tt>bool</tt> node map by
    51   ///calling \ref minCut(). (\ref minMinCut() and \ref maxMinCut() writes
    52   ///the inclusionwise minimum and maximum of the minimum value cuts,
    53   ///resp.)
    54   ///
    55   ///\param Graph The directed graph type the algorithm runs on.
    56   ///\param Num The number type of the capacities and the flow values.
    57   ///\param CapacityMap The capacity map type.
    58   ///\param FlowMap The flow map type.
    59   ///
    60   ///\author Jacint Szabo 
    61   ///\todo Second template parameter is superfluous
    62   template <typename Graph, typename Num,
    63 	    typename CapacityMap=typename Graph::template EdgeMap<Num>,
    64             typename FlowMap=typename Graph::template EdgeMap<Num> >
    65   class Preflow {
    66   protected:
    67     typedef typename Graph::Node Node;
    68     typedef typename Graph::NodeIt NodeIt;
    69     typedef typename Graph::EdgeIt EdgeIt;
    70     typedef typename Graph::OutEdgeIt OutEdgeIt;
    71     typedef typename Graph::InEdgeIt InEdgeIt;
    72 
    73     typedef typename Graph::template NodeMap<Node> NNMap;
    74     typedef typename std::vector<Node> VecNode;
    75 
    76     const Graph* _g;
    77     Node _source;
    78     Node _target;
    79     const CapacityMap* _capacity;
    80     FlowMap* _flow;
    81     int _node_num;      //the number of nodes of G
    82     
    83     typename Graph::template NodeMap<int> level;  
    84     typename Graph::template NodeMap<Num> excess;
    85 
    86     // constants used for heuristics
    87     static const int H0=20;
    88     static const int H1=1;
    89 
    90   public:
    91 
    92     ///\ref Exception for the case when s=t.
    93 
    94     ///\ref Exception for the case when the source equals the target.
    95     class InvalidArgument : public lemon::LogicError {
    96     public:
    97       virtual const char* exceptionName() const {
    98 	return "lemon::Preflow::InvalidArgument";
    99       }
   100     };
   101     
   102     
   103     ///Indicates the property of the starting flow map.
   104     
   105     ///Indicates the property of the starting flow map.
   106     ///The meanings are as follows:
   107     ///- \c ZERO_FLOW: constant zero flow
   108     ///- \c GEN_FLOW: any flow, i.e. the sum of the in-flows equals to
   109     ///the sum of the out-flows in every node except the \e source and
   110     ///the \e target.
   111     ///- \c PRE_FLOW: any preflow, i.e. the sum of the in-flows is at 
   112     ///least the sum of the out-flows in every node except the \e source.
   113     ///- \c NO_FLOW: indicates an unspecified edge map. \c flow will be 
   114     ///set to the constant zero flow in the beginning of
   115     ///the algorithm in this case.
   116     ///
   117     enum FlowEnum{
   118       NO_FLOW,
   119       ZERO_FLOW,
   120       GEN_FLOW,
   121       PRE_FLOW
   122     };
   123 
   124     ///Indicates the state of the preflow algorithm.
   125 
   126     ///Indicates the state of the preflow algorithm.
   127     ///The meanings are as follows:
   128     ///- \c AFTER_NOTHING: before running the algorithm or
   129     ///  at an unspecified state.
   130     ///- \c AFTER_PREFLOW_PHASE_1: right after running \c phase1
   131     ///- \c AFTER_PREFLOW_PHASE_2: after running \ref phase2()
   132     ///
   133     enum StatusEnum {
   134       AFTER_NOTHING,
   135       AFTER_PREFLOW_PHASE_1,      
   136       AFTER_PREFLOW_PHASE_2
   137     };
   138     
   139   protected: 
   140     FlowEnum flow_prop;
   141     StatusEnum status; // Do not needle this flag only if necessary.
   142     
   143   public: 
   144     ///The constructor of the class.
   145 
   146     ///The constructor of the class. 
   147     ///\param _gr The directed graph the algorithm runs on. 
   148     ///\param _s The source node.
   149     ///\param _t The target node.
   150     ///\param _cap The capacity of the edges. 
   151     ///\param _f The flow of the edges. 
   152     ///Except the graph, all of these parameters can be reset by
   153     ///calling \ref source, \ref target, \ref capacityMap and \ref
   154     ///flowMap, resp.
   155       Preflow(const Graph& _gr, Node _s, Node _t, 
   156 	      const CapacityMap& _cap, FlowMap& _f) :
   157 	_g(&_gr), _source(_s), _target(_t), _capacity(&_cap),
   158 	_flow(&_f), _node_num(countNodes(_gr)), level(_gr), excess(_gr,0), 
   159 	flow_prop(NO_FLOW), status(AFTER_NOTHING) { 
   160 	if ( _source==_target )
   161 	  throw InvalidArgument();
   162       }
   163     
   164 
   165                                                                               
   166     ///Runs the preflow algorithm.  
   167 
   168     ///Runs the preflow algorithm.
   169     ///
   170     void run() {
   171       phase1(flow_prop);
   172       phase2();
   173     }
   174     
   175     ///Runs the preflow algorithm.  
   176     
   177     ///Runs the preflow algorithm. 
   178     ///\pre The starting flow map must be
   179     /// - a constant zero flow if \c fp is \c ZERO_FLOW,
   180     /// - an arbitrary flow if \c fp is \c GEN_FLOW,
   181     /// - an arbitrary preflow if \c fp is \c PRE_FLOW,
   182     /// - any map if \c fp is NO_FLOW.
   183     ///If the starting flow map is a flow or a preflow then 
   184     ///the algorithm terminates faster.
   185     void run(FlowEnum fp) {
   186       flow_prop=fp;
   187       run();
   188     }
   189       
   190     ///Runs the first phase of the preflow algorithm.
   191 
   192     ///The preflow algorithm consists of two phases, this method runs
   193     ///the first phase. After the first phase the maximum flow value
   194     ///and a minimum value cut can already be computed, although a
   195     ///maximum flow is not yet obtained. So after calling this method
   196     ///\ref flowValue returns the value of a maximum flow and \ref
   197     ///minCut returns a minimum cut.     
   198     ///\warning \ref minMinCut and \ref maxMinCut do not give minimum
   199     ///value cuts unless calling \ref phase2.  
   200     ///\pre The starting flow must be 
   201     ///- a constant zero flow if \c fp is \c ZERO_FLOW, 
   202     ///- an arbitary flow if \c fp is \c GEN_FLOW, 
   203     ///- an arbitary preflow if \c fp is \c PRE_FLOW, 
   204     ///- any map if \c fp is NO_FLOW.
   205     void phase1(FlowEnum fp)
   206     {
   207       flow_prop=fp;
   208       phase1();
   209     }
   210 
   211     
   212     ///Runs the first phase of the preflow algorithm.
   213 
   214     ///The preflow algorithm consists of two phases, this method runs
   215     ///the first phase. After the first phase the maximum flow value
   216     ///and a minimum value cut can already be computed, although a
   217     ///maximum flow is not yet obtained. So after calling this method
   218     ///\ref flowValue returns the value of a maximum flow and \ref
   219     ///minCut returns a minimum cut.
   220     ///\warning \ref minMinCut() and \ref maxMinCut() do not
   221     ///give minimum value cuts unless calling \ref phase2().
   222     void phase1()
   223     {
   224       int heur0=(int)(H0*_node_num);  //time while running 'bound decrease'
   225       int heur1=(int)(H1*_node_num);  //time while running 'highest label'
   226       int heur=heur1;         //starting time interval (#of relabels)
   227       int numrelabel=0;
   228 
   229       bool what_heur=1;
   230       //It is 0 in case 'bound decrease' and 1 in case 'highest label'
   231 
   232       bool end=false;
   233       //Needed for 'bound decrease', true means no active 
   234       //nodes are above bound b.
   235 
   236       int k=_node_num-2;  //bound on the highest level under n containing a node
   237       int b=k;    //bound on the highest level under n of an active node
   238 
   239       VecNode first(_node_num, INVALID);
   240       NNMap next(*_g, INVALID);
   241 
   242       NNMap left(*_g, INVALID);
   243       NNMap right(*_g, INVALID);
   244       VecNode level_list(_node_num,INVALID);
   245       //List of the nodes in level i<n, set to n.
   246 
   247       preflowPreproc(first, next, level_list, left, right);
   248 
   249       //Push/relabel on the highest level active nodes.
   250       while ( true ) {
   251 	if ( b == 0 ) {
   252 	  if ( !what_heur && !end && k > 0 ) {
   253 	    b=k;
   254 	    end=true;
   255 	  } else break;
   256 	}
   257 
   258 	if ( first[b]==INVALID ) --b;
   259 	else {
   260 	  end=false;
   261 	  Node w=first[b];
   262 	  first[b]=next[w];
   263 	  int newlevel=push(w, next, first);
   264 	  if ( excess[w] > 0 ) relabel(w, newlevel, first, next, level_list, 
   265 				       left, right, b, k, what_heur);
   266 
   267 	  ++numrelabel;
   268 	  if ( numrelabel >= heur ) {
   269 	    numrelabel=0;
   270 	    if ( what_heur ) {
   271 	      what_heur=0;
   272 	      heur=heur0;
   273 	      end=false;
   274 	    } else {
   275 	      what_heur=1;
   276 	      heur=heur1;
   277 	      b=k;
   278 	    }
   279 	  }
   280 	}
   281       }
   282       flow_prop=PRE_FLOW;
   283       status=AFTER_PREFLOW_PHASE_1;
   284     }
   285     // Heuristics:
   286     //   2 phase
   287     //   gap
   288     //   list 'level_list' on the nodes on level i implemented by hand
   289     //   stack 'active' on the active nodes on level i      
   290     //   runs heuristic 'highest label' for H1*n relabels
   291     //   runs heuristic 'bound decrease' for H0*n relabels,
   292     //        starts with 'highest label'
   293     //   Parameters H0 and H1 are initialized to 20 and 1.
   294 
   295 
   296     ///Runs the second phase of the preflow algorithm.
   297 
   298     ///The preflow algorithm consists of two phases, this method runs
   299     ///the second phase. After calling \ref phase1() and then
   300     ///\ref phase2(),
   301     /// \ref flowMap() return a maximum flow, \ref flowValue
   302     ///returns the value of a maximum flow, \ref minCut returns a
   303     ///minimum cut, while the methods \ref minMinCut and \ref
   304     ///maxMinCut return the inclusionwise minimum and maximum cuts of
   305     ///minimum value, resp.  \pre \ref phase1 must be called before.
   306     void phase2()
   307     {
   308 
   309       int k=_node_num-2;  //bound on the highest level under n containing a node
   310       int b=k;    //bound on the highest level under n of an active node
   311 
   312     
   313       VecNode first(_node_num, INVALID);
   314       NNMap next(*_g, INVALID); 
   315       level.set(_source,0);
   316       std::queue<Node> bfs_queue;
   317       bfs_queue.push(_source);
   318 
   319       while ( !bfs_queue.empty() ) {
   320 
   321 	Node v=bfs_queue.front();
   322 	bfs_queue.pop();
   323 	int l=level[v]+1;
   324 
   325 	for(InEdgeIt e(*_g,v); e!=INVALID; ++e) {
   326 	  if ( (*_capacity)[e] <= (*_flow)[e] ) continue;
   327 	  Node u=_g->source(e);
   328 	  if ( level[u] >= _node_num ) {
   329 	    bfs_queue.push(u);
   330 	    level.set(u, l);
   331 	    if ( excess[u] > 0 ) {
   332 	      next.set(u,first[l]);
   333 	      first[l]=u;
   334 	    }
   335 	  }
   336 	}
   337 
   338 	for(OutEdgeIt e(*_g,v); e!=INVALID; ++e) {
   339 	  if ( 0 >= (*_flow)[e] ) continue;
   340 	  Node u=_g->target(e);
   341 	  if ( level[u] >= _node_num ) {
   342 	    bfs_queue.push(u);
   343 	    level.set(u, l);
   344 	    if ( excess[u] > 0 ) {
   345 	      next.set(u,first[l]);
   346 	      first[l]=u;
   347 	    }
   348 	  }
   349 	}
   350       }
   351       b=_node_num-2;
   352 
   353       while ( true ) {
   354 
   355 	if ( b == 0 ) break;
   356 	if ( first[b]==INVALID ) --b;
   357 	else {
   358 	  Node w=first[b];
   359 	  first[b]=next[w];
   360 	  int newlevel=push(w,next, first);
   361 	  
   362 	  //relabel
   363 	  if ( excess[w] > 0 ) {
   364 	    level.set(w,++newlevel);
   365 	    next.set(w,first[newlevel]);
   366 	    first[newlevel]=w;
   367 	    b=newlevel;
   368 	  }
   369 	} 
   370       } // while(true)
   371       flow_prop=GEN_FLOW;
   372       status=AFTER_PREFLOW_PHASE_2;
   373     }
   374 
   375     /// Returns the value of the maximum flow.
   376 
   377     /// Returns the value of the maximum flow by returning the excess
   378     /// of the target node \c t. This value equals to the value of
   379     /// the maximum flow already after running \ref phase1.
   380     Num flowValue() const {
   381       return excess[_target];
   382     }
   383 
   384 
   385     ///Returns a minimum value cut.
   386 
   387     ///Sets \c M to the characteristic vector of a minimum value
   388     ///cut. This method can be called both after running \ref
   389     ///phase1 and \ref phase2. It is much faster after
   390     ///\ref phase1.  \pre M should be a bool-valued node-map. \pre
   391     ///If \ref minCut() is called after \ref phase2() then M should
   392     ///be initialized to false.
   393     template<typename _CutMap>
   394     void minCut(_CutMap& M) const {
   395       switch ( status ) {
   396 	case AFTER_PREFLOW_PHASE_1:
   397 	for(NodeIt v(*_g); v!=INVALID; ++v) {
   398 	  if (level[v] < _node_num) {
   399 	    M.set(v, false);
   400 	  } else {
   401 	    M.set(v, true);
   402 	  }
   403 	}
   404 	break;
   405 	case AFTER_PREFLOW_PHASE_2:
   406 	minMinCut(M);
   407 	break;
   408 	case AFTER_NOTHING:
   409 	break;
   410       }
   411     }
   412 
   413     ///Returns the inclusionwise minimum of the minimum value cuts.
   414 
   415     ///Sets \c M to the characteristic vector of the minimum value cut
   416     ///which is inclusionwise minimum. It is computed by processing a
   417     ///bfs from the source node \c s in the residual graph.  \pre M
   418     ///should be a node map of bools initialized to false.  \pre \ref
   419     ///phase2 should already be run.
   420     template<typename _CutMap>
   421     void minMinCut(_CutMap& M) const {
   422 
   423       std::queue<Node> queue;
   424       M.set(_source,true);
   425       queue.push(_source);
   426       
   427       while (!queue.empty()) {
   428 	Node w=queue.front();
   429 	queue.pop();
   430 	
   431 	for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
   432 	  Node v=_g->target(e);
   433 	  if (!M[v] && (*_flow)[e] < (*_capacity)[e] ) {
   434 	    queue.push(v);
   435 	    M.set(v, true);
   436 	  }
   437 	}
   438 	
   439 	for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
   440 	  Node v=_g->source(e);
   441 	  if (!M[v] && (*_flow)[e] > 0 ) {
   442 	    queue.push(v);
   443 	    M.set(v, true);
   444 	  }
   445 	}
   446       }
   447     }
   448     
   449     ///Returns the inclusionwise maximum of the minimum value cuts.
   450 
   451     ///Sets \c M to the characteristic vector of the minimum value cut
   452     ///which is inclusionwise maximum. It is computed by processing a
   453     ///backward bfs from the target node \c t in the residual graph.
   454     ///\pre \ref phase2() or run() should already be run.
   455     template<typename _CutMap>
   456     void maxMinCut(_CutMap& M) const {
   457 
   458       for(NodeIt v(*_g) ; v!=INVALID; ++v) M.set(v, true);
   459 
   460       std::queue<Node> queue;
   461 
   462       M.set(_target,false);
   463       queue.push(_target);
   464 
   465       while (!queue.empty()) {
   466         Node w=queue.front();
   467 	queue.pop();
   468 
   469 	for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
   470 	  Node v=_g->source(e);
   471 	  if (M[v] && (*_flow)[e] < (*_capacity)[e] ) {
   472 	    queue.push(v);
   473 	    M.set(v, false);
   474 	  }
   475 	}
   476 
   477 	for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
   478 	  Node v=_g->target(e);
   479 	  if (M[v] && (*_flow)[e] > 0 ) {
   480 	    queue.push(v);
   481 	    M.set(v, false);
   482 	  }
   483 	}
   484       }
   485     }
   486 
   487     ///Sets the source node to \c _s.
   488 
   489     ///Sets the source node to \c _s.
   490     /// 
   491     void source(Node _s) { 
   492       _source=_s; 
   493       if ( flow_prop != ZERO_FLOW ) flow_prop=NO_FLOW;
   494       status=AFTER_NOTHING; 
   495     }
   496 
   497     ///Returns the source node.
   498 
   499     ///Returns the source node.
   500     /// 
   501     Node source() const { 
   502       return _source;
   503     }
   504 
   505     ///Sets the target node to \c _t.
   506 
   507     ///Sets the target node to \c _t.
   508     ///
   509     void target(Node _t) { 
   510       _target=_t; 
   511       if ( flow_prop == GEN_FLOW ) flow_prop=PRE_FLOW;
   512       status=AFTER_NOTHING; 
   513     }
   514 
   515     ///Returns the target node.
   516 
   517     ///Returns the target node.
   518     /// 
   519     Node target() const { 
   520       return _target;
   521     }
   522 
   523     /// Sets the edge map of the capacities to _cap.
   524 
   525     /// Sets the edge map of the capacities to _cap.
   526     /// 
   527     void capacityMap(const CapacityMap& _cap) { 
   528       _capacity=&_cap; 
   529       status=AFTER_NOTHING; 
   530     }
   531     /// Returns a reference to capacity map.
   532 
   533     /// Returns a reference to capacity map.
   534     /// 
   535     const CapacityMap &capacityMap() const { 
   536       return *_capacity;
   537     }
   538 
   539     /// Sets the edge map of the flows to _flow.
   540 
   541     /// Sets the edge map of the flows to _flow.
   542     /// 
   543     void flowMap(FlowMap& _f) { 
   544       _flow=&_f; 
   545       flow_prop=NO_FLOW;
   546       status=AFTER_NOTHING; 
   547     }
   548      
   549     /// Returns a reference to flow map.
   550 
   551     /// Returns a reference to flow map.
   552     /// 
   553     const FlowMap &flowMap() const { 
   554       return *_flow;
   555     }
   556 
   557   private:
   558 
   559     int push(Node w, NNMap& next, VecNode& first) {
   560 
   561       int lev=level[w];
   562       Num exc=excess[w];
   563       int newlevel=_node_num;       //bound on the next level of w
   564 
   565       for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
   566 	if ( (*_flow)[e] >= (*_capacity)[e] ) continue;
   567 	Node v=_g->target(e);
   568 
   569 	if( lev > level[v] ) { //Push is allowed now
   570 	  
   571 	  if ( excess[v]<=0 && v!=_target && v!=_source ) {
   572 	    next.set(v,first[level[v]]);
   573 	    first[level[v]]=v;
   574 	  }
   575 
   576 	  Num cap=(*_capacity)[e];
   577 	  Num flo=(*_flow)[e];
   578 	  Num remcap=cap-flo;
   579 	  
   580 	  if ( remcap >= exc ) { //A nonsaturating push.
   581 	    
   582 	    _flow->set(e, flo+exc);
   583 	    excess.set(v, excess[v]+exc);
   584 	    exc=0;
   585 	    break;
   586 
   587 	  } else { //A saturating push.
   588 	    _flow->set(e, cap);
   589 	    excess.set(v, excess[v]+remcap);
   590 	    exc-=remcap;
   591 	  }
   592 	} else if ( newlevel > level[v] ) newlevel = level[v];
   593       } //for out edges wv
   594 
   595       if ( exc > 0 ) {
   596 	for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
   597 	  
   598 	  if( (*_flow)[e] <= 0 ) continue;
   599 	  Node v=_g->source(e);
   600 
   601 	  if( lev > level[v] ) { //Push is allowed now
   602 
   603 	    if ( excess[v]<=0 && v!=_target && v!=_source ) {
   604 	      next.set(v,first[level[v]]);
   605 	      first[level[v]]=v;
   606 	    }
   607 
   608 	    Num flo=(*_flow)[e];
   609 
   610 	    if ( flo >= exc ) { //A nonsaturating push.
   611 
   612 	      _flow->set(e, flo-exc);
   613 	      excess.set(v, excess[v]+exc);
   614 	      exc=0;
   615 	      break;
   616 	    } else {  //A saturating push.
   617 
   618 	      excess.set(v, excess[v]+flo);
   619 	      exc-=flo;
   620 	      _flow->set(e,0);
   621 	    }
   622 	  } else if ( newlevel > level[v] ) newlevel = level[v];
   623 	} //for in edges vw
   624 
   625       } // if w still has excess after the out edge for cycle
   626 
   627       excess.set(w, exc);
   628       
   629       return newlevel;
   630     }
   631     
   632     
   633     
   634     void preflowPreproc(VecNode& first, NNMap& next, 
   635 			VecNode& level_list, NNMap& left, NNMap& right)
   636     {
   637       for(NodeIt v(*_g); v!=INVALID; ++v) level.set(v,_node_num);
   638       std::queue<Node> bfs_queue;
   639       
   640       if ( flow_prop == GEN_FLOW || flow_prop == PRE_FLOW ) {
   641 	//Reverse_bfs from t in the residual graph,
   642 	//to find the starting level.
   643 	level.set(_target,0);
   644 	bfs_queue.push(_target);
   645 	
   646 	while ( !bfs_queue.empty() ) {
   647 	  
   648 	  Node v=bfs_queue.front();
   649 	  bfs_queue.pop();
   650 	  int l=level[v]+1;
   651 	  
   652 	  for(InEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
   653 	    if ( (*_capacity)[e] <= (*_flow)[e] ) continue;
   654 	    Node w=_g->source(e);
   655 	    if ( level[w] == _node_num && w != _source ) {
   656 	      bfs_queue.push(w);
   657 	      Node z=level_list[l];
   658 	      if ( z!=INVALID ) left.set(z,w);
   659 	      right.set(w,z);
   660 	      level_list[l]=w;
   661 	      level.set(w, l);
   662 	    }
   663 	  }
   664 	  
   665 	  for(OutEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
   666 	    if ( 0 >= (*_flow)[e] ) continue;
   667 	    Node w=_g->target(e);
   668 	    if ( level[w] == _node_num && w != _source ) {
   669 	      bfs_queue.push(w);
   670 	      Node z=level_list[l];
   671 	      if ( z!=INVALID ) left.set(z,w);
   672 	      right.set(w,z);
   673 	      level_list[l]=w;
   674 	      level.set(w, l);
   675 	    }
   676 	  }
   677 	} //while
   678       } //if
   679 
   680 
   681       switch (flow_prop) {
   682 	case NO_FLOW:  
   683 	for(EdgeIt e(*_g); e!=INVALID; ++e) _flow->set(e,0);
   684 	case ZERO_FLOW:
   685 	for(NodeIt v(*_g); v!=INVALID; ++v) excess.set(v,0);
   686 	
   687 	//Reverse_bfs from t, to find the starting level.
   688 	level.set(_target,0);
   689 	bfs_queue.push(_target);
   690 	
   691 	while ( !bfs_queue.empty() ) {
   692 	  
   693 	  Node v=bfs_queue.front();
   694 	  bfs_queue.pop();
   695 	  int l=level[v]+1;
   696 	  
   697 	  for(InEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
   698 	    Node w=_g->source(e);
   699 	    if ( level[w] == _node_num && w != _source ) {
   700 	      bfs_queue.push(w);
   701 	      Node z=level_list[l];
   702 	      if ( z!=INVALID ) left.set(z,w);
   703 	      right.set(w,z);
   704 	      level_list[l]=w;
   705 	      level.set(w, l);
   706 	    }
   707 	  }
   708 	}
   709 	
   710 	//the starting flow
   711 	for(OutEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
   712 	  Num c=(*_capacity)[e];
   713 	  if ( c <= 0 ) continue;
   714 	  Node w=_g->target(e);
   715 	  if ( level[w] < _node_num ) {
   716 	    if ( excess[w] <= 0 && w!=_target ) { //putting into the stack
   717 	      next.set(w,first[level[w]]);
   718 	      first[level[w]]=w;
   719 	    }
   720 	    _flow->set(e, c);
   721 	    excess.set(w, excess[w]+c);
   722 	  }
   723 	}
   724 	break;
   725 
   726 	case GEN_FLOW:
   727 	for(NodeIt v(*_g); v!=INVALID; ++v) excess.set(v,0);
   728 	{
   729 	  Num exc=0;
   730 	  for(InEdgeIt e(*_g,_target) ; e!=INVALID; ++e) exc+=(*_flow)[e];
   731 	  for(OutEdgeIt e(*_g,_target) ; e!=INVALID; ++e) exc-=(*_flow)[e];
   732 	  excess.set(_target,exc);
   733 	}
   734 
   735 	//the starting flow
   736 	for(OutEdgeIt e(*_g,_source); e!=INVALID; ++e)	{
   737 	  Num rem=(*_capacity)[e]-(*_flow)[e];
   738 	  if ( rem <= 0 ) continue;
   739 	  Node w=_g->target(e);
   740 	  if ( level[w] < _node_num ) {
   741 	    if ( excess[w] <= 0 && w!=_target ) { //putting into the stack
   742 	      next.set(w,first[level[w]]);
   743 	      first[level[w]]=w;
   744 	    }   
   745 	    _flow->set(e, (*_capacity)[e]);
   746 	    excess.set(w, excess[w]+rem);
   747 	  }
   748 	}
   749 	
   750 	for(InEdgeIt e(*_g,_source); e!=INVALID; ++e) {
   751 	  if ( (*_flow)[e] <= 0 ) continue;
   752 	  Node w=_g->source(e);
   753 	  if ( level[w] < _node_num ) {
   754 	    if ( excess[w] <= 0 && w!=_target ) {
   755 	      next.set(w,first[level[w]]);
   756 	      first[level[w]]=w;
   757 	    }  
   758 	    excess.set(w, excess[w]+(*_flow)[e]);
   759 	    _flow->set(e, 0);
   760 	  }
   761 	}
   762 	break;
   763 
   764 	case PRE_FLOW:	
   765 	//the starting flow
   766 	for(OutEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
   767 	  Num rem=(*_capacity)[e]-(*_flow)[e];
   768 	  if ( rem <= 0 ) continue;
   769 	  Node w=_g->target(e);
   770 	  if ( level[w] < _node_num ) _flow->set(e, (*_capacity)[e]);
   771 	}
   772 	
   773 	for(InEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
   774 	  if ( (*_flow)[e] <= 0 ) continue;
   775 	  Node w=_g->source(e);
   776 	  if ( level[w] < _node_num ) _flow->set(e, 0);
   777 	}
   778 	
   779 	//computing the excess
   780 	for(NodeIt w(*_g); w!=INVALID; ++w) {
   781 	  Num exc=0;
   782 	  for(InEdgeIt e(*_g,w); e!=INVALID; ++e) exc+=(*_flow)[e];
   783 	  for(OutEdgeIt e(*_g,w); e!=INVALID; ++e) exc-=(*_flow)[e];
   784 	  excess.set(w,exc);
   785 	  
   786 	  //putting the active nodes into the stack
   787 	  int lev=level[w];
   788 	    if ( exc > 0 && lev < _node_num && Node(w) != _target ) {
   789 	      next.set(w,first[lev]);
   790 	      first[lev]=w;
   791 	    }
   792 	}
   793 	break;
   794       } //switch
   795     } //preflowPreproc
   796 
   797 
   798     void relabel(Node w, int newlevel, VecNode& first, NNMap& next, 
   799 		 VecNode& level_list, NNMap& left,
   800 		 NNMap& right, int& b, int& k, bool what_heur )
   801     {
   802 
   803       int lev=level[w];
   804 
   805       Node right_n=right[w];
   806       Node left_n=left[w];
   807 
   808       //unlacing starts
   809       if ( right_n!=INVALID ) {
   810 	if ( left_n!=INVALID ) {
   811 	  right.set(left_n, right_n);
   812 	  left.set(right_n, left_n);
   813 	} else {
   814 	  level_list[lev]=right_n;
   815 	  left.set(right_n, INVALID);
   816 	}
   817       } else {
   818 	if ( left_n!=INVALID ) {
   819 	  right.set(left_n, INVALID);
   820 	} else {
   821 	  level_list[lev]=INVALID;
   822 	}
   823       }
   824       //unlacing ends
   825 
   826       if ( level_list[lev]==INVALID ) {
   827 
   828 	//gapping starts
   829 	for (int i=lev; i!=k ; ) {
   830 	  Node v=level_list[++i];
   831 	  while ( v!=INVALID ) {
   832 	    level.set(v,_node_num);
   833 	    v=right[v];
   834 	  }
   835 	  level_list[i]=INVALID;
   836 	  if ( !what_heur ) first[i]=INVALID;
   837 	}
   838 
   839 	level.set(w,_node_num);
   840 	b=lev-1;
   841 	k=b;
   842 	//gapping ends
   843 
   844       } else {
   845 
   846 	if ( newlevel == _node_num ) level.set(w,_node_num);
   847 	else {
   848 	  level.set(w,++newlevel);
   849 	  next.set(w,first[newlevel]);
   850 	  first[newlevel]=w;
   851 	  if ( what_heur ) b=newlevel;
   852 	  if ( k < newlevel ) ++k;      //now k=newlevel
   853 	  Node z=level_list[newlevel];
   854 	  if ( z!=INVALID ) left.set(z,w);
   855 	  right.set(w,z);
   856 	  left.set(w,INVALID);
   857 	  level_list[newlevel]=w;
   858 	}
   859       }
   860     } //relabel
   861 
   862   }; 
   863 
   864   ///\ingroup flowalgs
   865   ///\brief Function type interface for Preflow algorithm.
   866   ///
   867   ///Function type interface for Preflow algorithm.
   868   ///\sa Preflow
   869   template<class GR, class CM, class FM>
   870   Preflow<GR,typename CM::Value,CM,FM> preflow(const GR &g,
   871 			    typename GR::Node source,
   872 			    typename GR::Node target,
   873 			    const CM &cap,
   874 			    FM &flow
   875 			    )
   876   {
   877     return Preflow<GR,typename CM::Value,CM,FM>(g,source,target,cap,flow);
   878   }
   879 
   880 } //namespace lemon
   881 
   882 #endif //LEMON_PREFLOW_H