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