src/hugo/max_flow.h
author alpar
Wed, 04 Aug 2004 18:55:24 +0000
changeset 753 f5382a084c07
parent 745 d976ba609099
child 757 8680351d0c28
permissions -rw-r--r--
doc change - one more todo (saveState()).
     1 // -*- C++ -*-
     2 #ifndef HUGO_MAX_FLOW_H
     3 #define HUGO_MAX_FLOW_H
     4 
     5 #include <vector>
     6 #include <queue>
     7 
     8 #include <hugo/graph_wrapper.h>
     9 #include <hugo/invalid.h>
    10 #include <hugo/maps.h>
    11 
    12 /// \file
    13 /// \ingroup galgs
    14 
    15 namespace hugo {
    16 
    17   /// \addtogroup galgs
    18   /// @{                                                                                                                                        
    19   ///Maximum flow algorithms class.
    20 
    21   ///This class provides various algorithms for finding a flow of
    22   ///maximum value in a directed graph. The \e source node, the \e
    23   ///target node, the \e capacity of the edges and the \e starting \e
    24   ///flow value of the edges should be passed to the algorithm through the
    25   ///constructor. It is possible to change these quantities using the
    26   ///functions \ref resetSource, \ref resetTarget, \ref resetCap and
    27   ///\ref resetFlow. Before any subsequent runs of any algorithm of
    28   ///the class \ref resetFlow should be called. 
    29 
    30   ///After running an algorithm of the class, the actual flow value 
    31   ///can be obtained by calling \ref flowValue(). The minimum
    32   ///value cut can be written into a \c node map of \c bools by
    33   ///calling \ref minCut. (\ref minMinCut and \ref maxMinCut writes
    34   ///the inclusionwise minimum and maximum of the minimum value
    35   ///cuts, resp.)                                                                                                                               
    36   ///\param Graph The directed graph type the algorithm runs on.
    37   ///\param Num The number type of the capacities and the flow values.
    38   ///\param CapMap The capacity map type.
    39   ///\param FlowMap The flow map type.                                                                                                           
    40   ///\author Marton Makai, Jacint Szabo 
    41   template <typename Graph, typename Num,
    42 	    typename CapMap=typename Graph::template EdgeMap<Num>,
    43             typename FlowMap=typename Graph::template EdgeMap<Num> >
    44   class MaxFlow {
    45   protected:
    46     typedef typename Graph::Node Node;
    47     typedef typename Graph::NodeIt NodeIt;
    48     typedef typename Graph::EdgeIt EdgeIt;
    49     typedef typename Graph::OutEdgeIt OutEdgeIt;
    50     typedef typename Graph::InEdgeIt InEdgeIt;
    51 
    52     typedef typename std::vector<Node> VecFirst;
    53     typedef typename Graph::template NodeMap<Node> NNMap;
    54     typedef typename std::vector<Node> VecNode;
    55 
    56     const Graph* g;
    57     Node s;
    58     Node t;
    59     const CapMap* capacity;
    60     FlowMap* flow;
    61     int n;      //the number of nodes of G
    62     typedef ResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;   
    63     //typedef ExpResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;
    64     typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
    65     typedef typename ResGW::Edge ResGWEdge;
    66     typedef typename Graph::template NodeMap<int> ReachedMap;
    67 
    68 
    69     //level works as a bool map in augmenting path algorithms and is
    70     //used by bfs for storing reached information.  In preflow, it
    71     //shows the levels of nodes.     
    72     ReachedMap level;
    73 
    74     //excess is needed only in preflow
    75     typename Graph::template NodeMap<Num> excess;
    76 
    77     // constants used for heuristics
    78     static const int H0=20;
    79     static const int H1=1;
    80 
    81   public:
    82 
    83     ///Indicates the property of the starting flow.
    84 
    85     ///Indicates the property of the starting flow. The meanings are as follows:
    86     ///- \c ZERO_FLOW: constant zero flow
    87     ///- \c GEN_FLOW: any flow, i.e. the sum of the in-flows equals to
    88     ///the sum of the out-flows in every node except the \e source and
    89     ///the \e target.
    90     ///- \c PRE_FLOW: any preflow, i.e. the sum of the in-flows is at 
    91     ///least the sum of the out-flows in every node except the \e source.
    92     ///- \c NO_FLOW: indicates an unspecified edge map. \ref flow will be 
    93     ///set to the constant zero flow in the beginning of the algorithm in this case.
    94     enum FlowEnum{
    95       ZERO_FLOW,
    96       GEN_FLOW,
    97       PRE_FLOW,
    98       NO_FLOW
    99     };
   100 
   101     enum StatusEnum {
   102       AFTER_NOTHING,
   103       AFTER_AUGMENTING,
   104       AFTER_FAST_AUGMENTING, 
   105       AFTER_PRE_FLOW_PHASE_1,      
   106       AFTER_PRE_FLOW_PHASE_2
   107     };
   108 
   109     /// Do not needle this flag only if necessary.
   110     StatusEnum status;
   111 
   112 //     int number_of_augmentations;
   113 
   114 
   115 //     template<typename IntMap>
   116 //     class TrickyReachedMap {
   117 //     protected:
   118 //       IntMap* map;
   119 //       int* number_of_augmentations;
   120 //     public:
   121 //       TrickyReachedMap(IntMap& _map, int& _number_of_augmentations) : 
   122 // 	map(&_map), number_of_augmentations(&_number_of_augmentations) { }
   123 //       void set(const Node& n, bool b) {
   124 // 	if (b)
   125 // 	  map->set(n, *number_of_augmentations);
   126 // 	else 
   127 // 	  map->set(n, *number_of_augmentations-1);
   128 //       }
   129 //       bool operator[](const Node& n) const { 
   130 // 	return (*map)[n]==*number_of_augmentations; 
   131 //       }
   132 //     };
   133     
   134     ///Constructor
   135 
   136     ///\todo Document, please.
   137     ///
   138     MaxFlow(const Graph& _G, Node _s, Node _t,
   139 	    const CapMap& _capacity, FlowMap& _flow) :
   140       g(&_G), s(_s), t(_t), capacity(&_capacity),
   141       flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0), 
   142       status(AFTER_NOTHING) { }
   143 
   144     ///Runs a maximum flow algorithm.
   145 
   146     ///Runs a preflow algorithm, which is the fastest maximum flow
   147     ///algorithm up-to-date. The default for \c fe is ZERO_FLOW.
   148     ///\pre The starting flow must be
   149     /// - a constant zero flow if \c fe is \c ZERO_FLOW,
   150     /// - an arbitary flow if \c fe is \c GEN_FLOW,
   151     /// - an arbitary preflow if \c fe is \c PRE_FLOW,
   152     /// - any map if \c fe is NO_FLOW.
   153     void run(FlowEnum fe=ZERO_FLOW) {
   154       preflow(fe);
   155     }
   156 
   157                                                                               
   158     ///Runs a preflow algorithm.  
   159 
   160     ///Runs a preflow algorithm. The preflow algorithms provide the
   161     ///fastest way to compute a maximum flow in a directed graph.
   162     ///\pre The starting flow must be
   163     /// - a constant zero flow if \c fe is \c ZERO_FLOW,
   164     /// - an arbitary flow if \c fe is \c GEN_FLOW,
   165     /// - an arbitary preflow if \c fe is \c PRE_FLOW,
   166     /// - any map if \c fe is NO_FLOW.
   167     ///
   168     ///\todo NO_FLOW should be the default flow.
   169     void preflow(FlowEnum fe) {
   170       preflowPhase1(fe);
   171       preflowPhase2();
   172     }
   173     // Heuristics:
   174     //   2 phase
   175     //   gap
   176     //   list 'level_list' on the nodes on level i implemented by hand
   177     //   stack 'active' on the active nodes on level i                                                                                    
   178     //   runs heuristic 'highest label' for H1*n relabels
   179     //   runs heuristic 'bound decrease' for H0*n relabels, starts with 'highest label'
   180     //   Parameters H0 and H1 are initialized to 20 and 1.
   181 
   182     ///Runs the first phase of the preflow algorithm.
   183 
   184     ///The preflow algorithm consists of two phases, this method runs the
   185     ///first phase. After the first phase the maximum flow value and a
   186     ///minimum value cut can already be computed, though a maximum flow
   187     ///is not yet obtained. So after calling this method \ref flowValue
   188     ///and \ref actMinCut gives proper results.
   189     ///\warning: \ref minCut, \ref minMinCut and \ref maxMinCut do not
   190     ///give minimum value cuts unless calling \ref preflowPhase2.
   191     ///\pre The starting flow must be
   192     /// - a constant zero flow if \c fe is \c ZERO_FLOW,
   193     /// - an arbitary flow if \c fe is \c GEN_FLOW,
   194     /// - an arbitary preflow if \c fe is \c PRE_FLOW,
   195     /// - any map if \c fe is NO_FLOW.
   196     void preflowPhase1(FlowEnum fe)
   197     {
   198 
   199       int heur0=(int)(H0*n);  //time while running 'bound decrease'
   200       int heur1=(int)(H1*n);  //time while running 'highest label'
   201       int heur=heur1;         //starting time interval (#of relabels)
   202       int numrelabel=0;
   203 
   204       bool what_heur=1;
   205       //It is 0 in case 'bound decrease' and 1 in case 'highest label'
   206 
   207       bool end=false;
   208       //Needed for 'bound decrease', true means no active nodes are above bound
   209       //b.
   210 
   211       int k=n-2;  //bound on the highest level under n containing a node
   212       int b=k;    //bound on the highest level under n of an active node
   213 
   214       VecFirst first(n, INVALID);
   215       NNMap next(*g, INVALID); //maybe INVALID is not needed
   216 
   217       NNMap left(*g, INVALID);
   218       NNMap right(*g, INVALID);
   219       VecNode level_list(n,INVALID);
   220       //List of the nodes in level i<n, set to n.
   221 
   222       preflowPreproc(fe, next, first, level_list, left, right);
   223       //End of preprocessing
   224 
   225       //Push/relabel on the highest level active nodes.
   226       while ( true ) {
   227 	if ( b == 0 ) {
   228 	  if ( !what_heur && !end && k > 0 ) {
   229 	    b=k;
   230 	    end=true;
   231 	  } else break;
   232 	}
   233 
   234 	if ( !g->valid(first[b]) ) --b;
   235 	else {
   236 	  end=false;
   237 	  Node w=first[b];
   238 	  first[b]=next[w];
   239 	  int newlevel=push(w, next, first);
   240 	  if ( excess[w] > 0 ) relabel(w, newlevel, next, first, level_list,
   241 				       left, right, b, k, what_heur);
   242 
   243 	  ++numrelabel;
   244 	  if ( numrelabel >= heur ) {
   245 	    numrelabel=0;
   246 	    if ( what_heur ) {
   247 	      what_heur=0;
   248 	      heur=heur0;
   249 	      end=false;
   250 	    } else {
   251 	      what_heur=1;
   252 	      heur=heur1;
   253 	      b=k;
   254 	    }
   255 	  }
   256 	}
   257       }
   258 
   259       status=AFTER_PRE_FLOW_PHASE_1;
   260     }
   261 
   262 
   263     ///Runs the second phase of the preflow algorithm.
   264 
   265     ///The preflow algorithm consists of two phases, this method runs
   266     ///the second phase. After calling \ref preflowPhase1 and then
   267     ///\ref preflowPhase2 the methods \ref flowValue, \ref minCut,
   268     ///\ref minMinCut and \ref maxMinCut give proper results.
   269     ///\pre \ref preflowPhase1 must be called before.
   270     void preflowPhase2()
   271     {
   272 
   273       int k=n-2;  //bound on the highest level under n containing a node
   274       int b=k;    //bound on the highest level under n of an active node
   275 
   276     
   277       VecFirst first(n, INVALID);
   278       NNMap next(*g, INVALID); //maybe INVALID is not needed
   279       level.set(s,0);
   280       std::queue<Node> bfs_queue;
   281       bfs_queue.push(s);
   282 
   283       while (!bfs_queue.empty()) {
   284 
   285 	Node v=bfs_queue.front();
   286 	bfs_queue.pop();
   287 	int l=level[v]+1;
   288 
   289 	InEdgeIt e;
   290 	for(g->first(e,v); g->valid(e); g->next(e)) {
   291 	  if ( (*capacity)[e] <= (*flow)[e] ) continue;
   292 	  Node u=g->tail(e);
   293 	  if ( level[u] >= n ) {
   294 	    bfs_queue.push(u);
   295 	    level.set(u, l);
   296 	    if ( excess[u] > 0 ) {
   297 	      next.set(u,first[l]);
   298 	      first[l]=u;
   299 	    }
   300 	  }
   301 	}
   302 
   303 	OutEdgeIt f;
   304 	for(g->first(f,v); g->valid(f); g->next(f)) {
   305 	  if ( 0 >= (*flow)[f] ) continue;
   306 	  Node u=g->head(f);
   307 	  if ( level[u] >= n ) {
   308 	    bfs_queue.push(u);
   309 	    level.set(u, l);
   310 	    if ( excess[u] > 0 ) {
   311 	      next.set(u,first[l]);
   312 	      first[l]=u;
   313 	    }
   314 	  }
   315 	}
   316       }
   317       b=n-2;
   318 
   319       while ( true ) {
   320 
   321 	if ( b == 0 ) break;
   322 
   323 	if ( !g->valid(first[b]) ) --b;
   324 	else {
   325 
   326 	  Node w=first[b];
   327 	  first[b]=next[w];
   328 	  int newlevel=push(w,next, first/*active*/);
   329 
   330 	  //relabel
   331 	  if ( excess[w] > 0 ) {
   332 	    level.set(w,++newlevel);
   333 	    next.set(w,first[newlevel]);
   334 	    first[newlevel]=w;
   335 	    b=newlevel;
   336 	  }
   337 	} 
   338       } // while(true)
   339 
   340       status=AFTER_PRE_FLOW_PHASE_2;
   341     }
   342 
   343 
   344     /// Returns the maximum value of a flow.
   345 
   346     /// Returns the maximum value of a flow, by counting the 
   347     /// over-flow of the target node \ref t.
   348     /// It can be called already after running \ref preflowPhase1.
   349     Num flowValue() const {
   350       Num a=0;
   351       for(InEdgeIt e(*g,t);g->valid(e);g->next(e)) a+=(*flow)[e];
   352       for(OutEdgeIt e(*g,t);g->valid(e);g->next(e)) a-=(*flow)[e];
   353       return a;
   354       //marci figyu: excess[t] epp ezt adja preflow 1. fazisa utan   
   355     }
   356 
   357 
   358     ///Returns a minimum value cut after calling \ref preflowPhase1.
   359 
   360     ///After the first phase of the preflow algorithm the maximum flow
   361     ///value and a minimum value cut can already be computed. This
   362     ///method can be called after running \ref preflowPhase1 for
   363     ///obtaining a minimum value cut.
   364     /// \warning Gives proper result only right after calling \ref
   365     /// preflowPhase1.
   366     /// \todo We have to make some status variable which shows the
   367     /// actual state
   368     /// of the class. This enables us to determine which methods are valid
   369     /// for MinCut computation
   370     template<typename _CutMap>
   371     void actMinCut(_CutMap& M) const {
   372       NodeIt v;
   373       switch (status) {
   374       case AFTER_PRE_FLOW_PHASE_1:
   375 	for(g->first(v); g->valid(v); g->next(v)) {
   376 	  if (level[v] < n) {
   377 	    M.set(v, false);
   378 	  } else {
   379 	    M.set(v, true);
   380 	  }
   381 	}
   382 	break;
   383       case AFTER_PRE_FLOW_PHASE_2:
   384       case AFTER_NOTHING:
   385       case AFTER_AUGMENTING:
   386       case AFTER_FAST_AUGMENTING:
   387 	minMinCut(M);
   388 	break;
   389       }
   390     }
   391 
   392     ///Returns the inclusionwise minimum of the minimum value cuts.
   393 
   394     ///Sets \c M to the characteristic vector of the minimum value cut
   395     ///which is inclusionwise minimum. It is computed by processing
   396     ///a bfs from the source node \c s in the residual graph.
   397     ///\pre M should be a node map of bools initialized to false.
   398     ///\pre \c flow must be a maximum flow.
   399     template<typename _CutMap>
   400     void minMinCut(_CutMap& M) const {
   401       std::queue<Node> queue;
   402 
   403       M.set(s,true);
   404       queue.push(s);
   405 
   406       while (!queue.empty()) {
   407         Node w=queue.front();
   408 	queue.pop();
   409 
   410 	OutEdgeIt e;
   411 	for(g->first(e,w) ; g->valid(e); g->next(e)) {
   412 	  Node v=g->head(e);
   413 	  if (!M[v] && (*flow)[e] < (*capacity)[e] ) {
   414 	    queue.push(v);
   415 	    M.set(v, true);
   416 	  }
   417 	}
   418 
   419 	InEdgeIt f;
   420 	for(g->first(f,w) ; g->valid(f); g->next(f)) {
   421 	  Node v=g->tail(f);
   422 	  if (!M[v] && (*flow)[f] > 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 M should be a node map of bools initialized to false.
   436     ///\pre \c flow must be a maximum flow. 
   437     template<typename _CutMap>
   438     void maxMinCut(_CutMap& M) const {
   439 
   440       NodeIt v;
   441       for(g->first(v) ; g->valid(v); g->next(v)) {
   442 	M.set(v, true);
   443       }
   444 
   445       std::queue<Node> queue;
   446 
   447       M.set(t,false);
   448       queue.push(t);
   449 
   450       while (!queue.empty()) {
   451         Node w=queue.front();
   452 	queue.pop();
   453 
   454 	InEdgeIt e;
   455 	for(g->first(e,w) ; g->valid(e); g->next(e)) {
   456 	  Node v=g->tail(e);
   457 	  if (M[v] && (*flow)[e] < (*capacity)[e] ) {
   458 	    queue.push(v);
   459 	    M.set(v, false);
   460 	  }
   461 	}
   462 
   463 	OutEdgeIt f;
   464 	for(g->first(f,w) ; g->valid(f); g->next(f)) {
   465 	  Node v=g->head(f);
   466 	  if (M[v] && (*flow)[f] > 0 ) {
   467 	    queue.push(v);
   468 	    M.set(v, false);
   469 	  }
   470 	}
   471       }
   472     }
   473 
   474     ///Returns a minimum value cut.
   475 
   476     ///Sets \c M to the characteristic vector of a minimum value cut.
   477     ///\pre M should be a node map of bools initialized to false.
   478     ///\pre \c flow must be a maximum flow.    
   479     template<typename CutMap>
   480     void minCut(CutMap& M) const { minMinCut(M); }
   481 
   482     ///Resets the source node to \c _s.
   483 
   484     ///Resets the source node to \c _s.
   485     /// 
   486     void resetSource(Node _s) { s=_s; status=AFTER_NOTHING; }
   487 
   488     ///Resets the target node to \c _t.
   489 
   490     ///Resets the target node to \c _t.
   491     ///
   492     void resetTarget(Node _t) { t=_t; status=AFTER_NOTHING; }
   493 
   494     /// Resets the edge map of the capacities to _cap.
   495 
   496     /// Resets the edge map of the capacities to _cap.
   497     /// 
   498     void resetCap(const CapMap& _cap)
   499     { capacity=&_cap; status=AFTER_NOTHING; }
   500 
   501     /// Resets the edge map of the flows to _flow.
   502 
   503     /// Resets the edge map of the flows to _flow.
   504     /// 
   505     void resetFlow(FlowMap& _flow) { flow=&_flow; status=AFTER_NOTHING; }
   506 
   507 
   508   private:
   509 
   510     int push(Node w, NNMap& next, VecFirst& 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       OutEdgeIt e;
   517       for(g->first(e,w); g->valid(e); g->next(e)) {
   518 
   519 	if ( (*flow)[e] >= (*capacity)[e] ) continue;
   520 	Node v=g->head(e);
   521 
   522 	if( lev > level[v] ) { //Push is allowed now
   523 
   524 	  if ( excess[v]<=0 && v!=t && v!=s ) {
   525 	    next.set(v,first[level[v]]);
   526 	    first[level[v]]=v;
   527 	  }
   528 
   529 	  Num cap=(*capacity)[e];
   530 	  Num flo=(*flow)[e];
   531 	  Num remcap=cap-flo;
   532 
   533 	  if ( remcap >= exc ) { //A nonsaturating push.
   534 
   535 	    flow->set(e, flo+exc);
   536 	    excess.set(v, excess[v]+exc);
   537 	    exc=0;
   538 	    break;
   539 
   540 	  } else { //A saturating push.
   541 	    flow->set(e, cap);
   542 	    excess.set(v, excess[v]+remcap);
   543 	    exc-=remcap;
   544 	  }
   545 	} else if ( newlevel > level[v] ) newlevel = level[v];
   546       } //for out edges wv
   547 
   548       if ( exc > 0 ) {
   549 	InEdgeIt e;
   550 	for(g->first(e,w); g->valid(e); g->next(e)) {
   551 
   552 	  if( (*flow)[e] <= 0 ) continue;
   553 	  Node v=g->tail(e);
   554 
   555 	  if( lev > level[v] ) { //Push is allowed now
   556 
   557 	    if ( excess[v]<=0 && v!=t && v!=s ) {
   558 	      next.set(v,first[level[v]]);
   559 	      first[level[v]]=v;
   560 	    }
   561 
   562 	    Num flo=(*flow)[e];
   563 
   564 	    if ( flo >= exc ) { //A nonsaturating push.
   565 
   566 	      flow->set(e, flo-exc);
   567 	      excess.set(v, excess[v]+exc);
   568 	      exc=0;
   569 	      break;
   570 	    } else {  //A saturating push.
   571 
   572 	      excess.set(v, excess[v]+flo);
   573 	      exc-=flo;
   574 	      flow->set(e,0);
   575 	    }
   576 	  } else if ( newlevel > level[v] ) newlevel = level[v];
   577 	} //for in edges vw
   578 
   579       } // if w still has excess after the out edge for cycle
   580 
   581       excess.set(w, exc);
   582 
   583       return newlevel;
   584     }
   585 
   586 
   587 
   588     void preflowPreproc(FlowEnum fe, NNMap& next, VecFirst& first,
   589 			VecNode& level_list, NNMap& left, NNMap& right)
   590     {
   591       switch (fe) { //setting excess
   592 	case NO_FLOW: 
   593 	{
   594 	  EdgeIt e;
   595 	  for(g->first(e); g->valid(e); g->next(e)) flow->set(e,0);
   596 	  
   597 	  NodeIt v;
   598 	  for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
   599 	  break;
   600 	}
   601 	case ZERO_FLOW: 
   602 	{
   603 	  NodeIt v;
   604 	  for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
   605 	  break;
   606 	}
   607 	case GEN_FLOW:
   608 	{
   609 	  NodeIt v;
   610 	  for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
   611 
   612 	  Num exc=0;
   613 	  InEdgeIt e;
   614 	  for(g->first(e,t); g->valid(e); g->next(e)) exc+=(*flow)[e];
   615 	  OutEdgeIt f;
   616 	  for(g->first(f,t); g->valid(f); g->next(f)) exc-=(*flow)[f];
   617 	  excess.set(t,exc);
   618 	  break;
   619 	}
   620 	default: break;
   621       }
   622 
   623       NodeIt v;
   624       for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
   625       //setting each node to level n
   626       
   627       std::queue<Node> bfs_queue;
   628 
   629 
   630       switch (fe) {
   631       case NO_FLOW:   //flow is already set to const zero
   632       case ZERO_FLOW:
   633 	{
   634 	  //Reverse_bfs from t, to find the starting level.
   635 	  level.set(t,0);
   636 	  bfs_queue.push(t);
   637 
   638 	  while (!bfs_queue.empty()) {
   639 
   640 	    Node v=bfs_queue.front();
   641 	    bfs_queue.pop();
   642 	    int l=level[v]+1;
   643 
   644 	    InEdgeIt e;
   645 	    for(g->first(e,v); g->valid(e); g->next(e)) {
   646 	      Node w=g->tail(e);
   647 	      if ( level[w] == n && w != s ) {
   648 		bfs_queue.push(w);
   649 		Node z=level_list[l];
   650 		if ( g->valid(z) ) left.set(z,w);
   651 		right.set(w,z);
   652 		level_list[l]=w;
   653 		level.set(w, l);
   654 	      }
   655 	    }
   656 	  }
   657 
   658 	  //the starting flow
   659 	  OutEdgeIt e;
   660 	  for(g->first(e,s); g->valid(e); g->next(e))
   661 	    {
   662 	      Num c=(*capacity)[e];
   663 	      if ( c <= 0 ) continue;
   664 	      Node w=g->head(e);
   665 	      if ( level[w] < n ) {
   666 		if ( excess[w] <= 0 && w!=t ) //putting into the stack
   667 		  { 
   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 
   678       case GEN_FLOW:
   679 	{
   680 	  //Reverse_bfs from t in the residual graph,
   681 	  //to find the starting level.
   682 	  level.set(t,0);
   683 	  bfs_queue.push(t);
   684 
   685 	  while (!bfs_queue.empty()) {
   686 
   687 	    Node v=bfs_queue.front();
   688 	    bfs_queue.pop();
   689 	    int l=level[v]+1;
   690 
   691 	    InEdgeIt e;
   692 	    for(g->first(e,v); g->valid(e); g->next(e)) {
   693 	      if ( (*capacity)[e] <= (*flow)[e] ) continue;
   694 	      Node w=g->tail(e);
   695 	      if ( level[w] == n && w != s ) {
   696 		bfs_queue.push(w);
   697 		Node z=level_list[l];
   698 		if ( g->valid(z) ) left.set(z,w);
   699 		right.set(w,z);
   700 		level_list[l]=w;
   701 		level.set(w, l);
   702 	      }
   703 	    }
   704 
   705 	    OutEdgeIt f;
   706 	    for(g->first(f,v); g->valid(f); g->next(f)) {
   707 	      if ( 0 >= (*flow)[f] ) continue;
   708 	      Node w=g->head(f);
   709 	      if ( level[w] == n && w != s ) {
   710 		bfs_queue.push(w);
   711 		Node z=level_list[l];
   712 		if ( g->valid(z) ) left.set(z,w);
   713 		right.set(w,z);
   714 		level_list[l]=w;
   715 		level.set(w, l);
   716 	      }
   717 	    }
   718 	  }
   719 
   720 	  //the starting flow
   721 	  OutEdgeIt e;
   722 	  for(g->first(e,s); g->valid(e); g->next(e))
   723 	    {
   724 	      Num rem=(*capacity)[e]-(*flow)[e];
   725 	      if ( rem <= 0 ) continue;
   726 	      Node w=g->head(e);
   727 	      if ( level[w] < n ) {
   728 		if ( excess[w] <= 0 && w!=t ) //putting into the stack
   729 		  {
   730 		    next.set(w,first[level[w]]);
   731 		    first[level[w]]=w;
   732 		  }   
   733 		flow->set(e, (*capacity)[e]);
   734 		excess.set(w, excess[w]+rem);
   735 	      }
   736 	    }
   737 
   738 	  InEdgeIt f;
   739 	  for(g->first(f,s); g->valid(f); g->next(f))
   740 	    {
   741 	      if ( (*flow)[f] <= 0 ) continue;
   742 	      Node w=g->tail(f);
   743 	      if ( level[w] < n ) {
   744 		if ( excess[w] <= 0 && w!=t )
   745 		  {
   746 		    next.set(w,first[level[w]]);
   747 		    first[level[w]]=w;
   748 		  }  
   749 		excess.set(w, excess[w]+(*flow)[f]);
   750 		flow->set(f, 0);
   751 	      }
   752 	    }
   753 	  break;
   754 	} //case GEN_FLOW
   755     
   756       case PRE_FLOW:
   757 	{
   758 	  //Reverse_bfs from t in the residual graph,
   759 	  //to find the starting level.
   760 	  level.set(t,0);
   761 	  bfs_queue.push(t);
   762 
   763 	  while (!bfs_queue.empty()) {
   764 
   765 	    Node v=bfs_queue.front();
   766 	    bfs_queue.pop();
   767 	    int l=level[v]+1;
   768 
   769 	    InEdgeIt e;
   770 	    for(g->first(e,v); g->valid(e); g->next(e)) {
   771 	      if ( (*capacity)[e] <= (*flow)[e] ) continue;
   772 	      Node w=g->tail(e);
   773 	      if ( level[w] == n && w != s ) {
   774 		bfs_queue.push(w);
   775 		Node z=level_list[l];
   776 		if ( g->valid(z) ) left.set(z,w);
   777 		right.set(w,z);
   778 		level_list[l]=w;
   779 		level.set(w, l);
   780 	      }
   781 	    }
   782 
   783 	    OutEdgeIt f;
   784 	    for(g->first(f,v); g->valid(f); g->next(f)) {
   785 	      if ( 0 >= (*flow)[f] ) continue;
   786 	      Node w=g->head(f);
   787 	      if ( level[w] == n && w != s ) {
   788 		bfs_queue.push(w);
   789 		Node z=level_list[l];
   790 		if ( g->valid(z) ) left.set(z,w);
   791 		right.set(w,z);
   792 		level_list[l]=w;
   793 		level.set(w, l);
   794 	      }
   795 	    }
   796 	  }
   797 
   798 
   799 	  //the starting flow
   800 	  OutEdgeIt e;
   801 	  for(g->first(e,s); g->valid(e); g->next(e))
   802 	    {
   803 	      Num rem=(*capacity)[e]-(*flow)[e];
   804 	      if ( rem <= 0 ) continue;
   805 	      Node w=g->head(e);
   806 	      if ( level[w] < n ) {
   807 		flow->set(e, (*capacity)[e]);
   808 		excess.set(w, excess[w]+rem);
   809 	      }
   810 	    }
   811 
   812 	  InEdgeIt f;
   813 	  for(g->first(f,s); g->valid(f); g->next(f))
   814 	    {
   815 	      if ( (*flow)[f] <= 0 ) continue;
   816 	      Node w=g->tail(f);
   817 	      if ( level[w] < n ) {
   818 		excess.set(w, excess[w]+(*flow)[f]);
   819 		flow->set(f, 0);
   820 	      }
   821 	    }
   822 	  
   823 	  NodeIt w; //computing the excess
   824 	  for(g->first(w); g->valid(w); g->next(w)) {
   825 	    Num exc=0;
   826 
   827 	    InEdgeIt e;
   828 	    for(g->first(e,w); g->valid(e); g->next(e)) exc+=(*flow)[e];
   829 	    OutEdgeIt f;
   830 	    for(g->first(f,w); g->valid(f); g->next(f)) exc-=(*flow)[f];
   831 
   832 	    excess.set(w,exc);
   833 
   834 	    //putting the active nodes into the stack
   835 	    int lev=level[w];
   836 	    if ( exc > 0 && lev < n && w != t ) 
   837 	      {
   838 		next.set(w,first[lev]);
   839 		first[lev]=w;
   840 	      }
   841 	  }
   842 	  break;
   843 	} //case PRE_FLOW
   844       }
   845     } //preflowPreproc
   846 
   847 
   848     void relabel(Node w, int newlevel, NNMap& next, VecFirst& first,
   849 		 VecNode& level_list, NNMap& left,
   850 		 NNMap& right, int& b, int& k, bool what_heur )
   851     {
   852 
   853       Num lev=level[w];
   854 
   855       Node right_n=right[w];
   856       Node left_n=left[w];
   857 
   858       //unlacing starts
   859       if ( g->valid(right_n) ) {
   860 	if ( g->valid(left_n) ) {
   861 	  right.set(left_n, right_n);
   862 	  left.set(right_n, left_n);
   863 	} else {
   864 	  level_list[lev]=right_n;
   865 	  left.set(right_n, INVALID);
   866 	}
   867       } else {
   868 	if ( g->valid(left_n) ) {
   869 	  right.set(left_n, INVALID);
   870 	} else {
   871 	  level_list[lev]=INVALID;
   872 	}
   873       }
   874       //unlacing ends
   875 
   876       if ( !g->valid(level_list[lev]) ) {
   877 
   878 	//gapping starts
   879 	for (int i=lev; i!=k ; ) {
   880 	  Node v=level_list[++i];
   881 	  while ( g->valid(v) ) {
   882 	    level.set(v,n);
   883 	    v=right[v];
   884 	  }
   885 	  level_list[i]=INVALID;
   886 	  if ( !what_heur ) first[i]=INVALID;
   887 	}
   888 
   889 	level.set(w,n);
   890 	b=lev-1;
   891 	k=b;
   892 	//gapping ends
   893 
   894       } else {
   895 
   896 	if ( newlevel == n ) level.set(w,n);
   897 	else {
   898 	  level.set(w,++newlevel);
   899 	  next.set(w,first[newlevel]);
   900 	  first[newlevel]=w;
   901 	  if ( what_heur ) b=newlevel;
   902 	  if ( k < newlevel ) ++k;      //now k=newlevel
   903 	  Node z=level_list[newlevel];
   904 	  if ( g->valid(z) ) left.set(z,w);
   905 	  right.set(w,z);
   906 	  left.set(w,INVALID);
   907 	  level_list[newlevel]=w;
   908 	}
   909       }
   910     } //relabel
   911 
   912     void printexcess() {////
   913       std::cout << "Excesses:" <<std::endl;
   914 
   915       NodeIt v;
   916       for(g->first(v); g->valid(v); g->next(v)) {
   917 	std::cout << 1+(g->id(v)) << ":" << excess[v]<<std::endl; 
   918       }
   919     }
   920 
   921  void printlevel() {////
   922       std::cout << "Levels:" <<std::endl;
   923 
   924       NodeIt v;
   925       for(g->first(v); g->valid(v); g->next(v)) {
   926 	std::cout << 1+(g->id(v)) << ":" << level[v]<<std::endl; 
   927       }
   928     }
   929 
   930 void printactive() {////
   931       std::cout << "Levels:" <<std::endl;
   932 
   933       NodeIt v;
   934       for(g->first(v); g->valid(v); g->next(v)) {
   935 	std::cout << 1+(g->id(v)) << ":" << level[v]<<std::endl; 
   936       }
   937     }
   938 
   939 
   940   };  //class MaxFlow
   941 } //namespace hugo
   942 
   943 #endif //HUGO_MAX_FLOW_H
   944 
   945 
   946 
   947