src/work/jacint/max_flow.h
author marci
Thu, 06 May 2004 17:01:31 +0000
changeset 557 9c0ce0a1f000
parent 555 995bc1f1a3ce
child 586 04fdffd38e89
permissions -rw-r--r--
(none)
     1 // -*- C++ -*-
     2 
     3 /*
     4   Heuristics: 
     5   2 phase
     6   gap
     7   list 'level_list' on the nodes on level i implemented by hand
     8   stack 'active' on the active nodes on level i
     9   runs heuristic 'highest label' for H1*n relabels
    10   runs heuristic 'bound decrease' for H0*n relabels, starts with 'highest label'
    11  
    12   Parameters H0 and H1 are initialized to 20 and 1.
    13 
    14   Constructors:
    15 
    16   Preflow(Graph, Node, Node, CapMap, FlowMap, bool) : bool must be false if 
    17   FlowMap is not constant zero, and should be true if it is
    18 
    19   Members:
    20 
    21   void run()
    22 
    23   Num flowValue() : returns the value of a maximum flow
    24 
    25   void minMinCut(CutMap& M) : sets M to the characteristic vector of the 
    26   minimum min cut. M should be a map of bools initialized to false. ??Is it OK?
    27 
    28   void maxMinCut(CutMap& M) : sets M to the characteristic vector of the 
    29   maximum min cut. M should be a map of bools initialized to false.
    30 
    31   void minCut(CutMap& M) : sets M to the characteristic vector of 
    32   a min cut. M should be a map of bools initialized to false.
    33 
    34 */
    35 
    36 #ifndef HUGO_MAX_FLOW_H
    37 #define HUGO_MAX_FLOW_H
    38 
    39 #define H0 20
    40 #define H1 1
    41 
    42 #include <vector>
    43 #include <queue>
    44 #include <stack>
    45 
    46 #include <hugo/graph_wrapper.h>
    47 #include <bfs_iterator.h>
    48 #include <hugo/invalid.h>
    49 #include <hugo/maps.h>
    50 #include <for_each_macros.h>
    51 
    52 /// \file
    53 /// \brief Dimacs file format reader.
    54 
    55 namespace hugo {
    56 
    57 
    58 //  ///\author Marton Makai, Jacint Szabo
    59   /// A class for computing max flows and related quantities.
    60   template <typename Graph, typename Num, 
    61 	    typename CapMap=typename Graph::template EdgeMap<Num>, 
    62             typename FlowMap=typename Graph::template EdgeMap<Num> >
    63   class MaxFlow {
    64     
    65     typedef typename Graph::Node Node;
    66     typedef typename Graph::NodeIt NodeIt;
    67     typedef typename Graph::OutEdgeIt OutEdgeIt;
    68     typedef typename Graph::InEdgeIt InEdgeIt;
    69 
    70     typedef typename std::vector<std::stack<Node> > VecStack;
    71     typedef typename Graph::template NodeMap<Node> NNMap;
    72     typedef typename std::vector<Node> VecNode;
    73 
    74     const Graph* g;
    75     Node s;
    76     Node t;
    77     const CapMap* capacity;  
    78     FlowMap* flow;
    79     int n;      //the number of nodes of G
    80     typedef ResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;
    81     typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
    82     typedef typename ResGW::Edge ResGWEdge;
    83     //typedef typename ResGW::template NodeMap<bool> ReachedMap;
    84     typedef typename Graph::template NodeMap<int> ReachedMap;
    85     ReachedMap level;
    86     //level works as a bool map in augmenting path algorithms 
    87     //and is used by bfs for storing reached information.
    88     //In preflow, it shows levels of nodes.
    89     //typename Graph::template NodeMap<int> level;    
    90     typename Graph::template NodeMap<Num> excess; 
    91 //   protected:
    92 //     MaxFlow() { }
    93 //     void set(const Graph& _G, Node _s, Node _t, const CapMap& _capacity, 
    94 // 	     FlowMap& _flow) 
    95 //       {
    96 // 	g=&_G; 
    97 // 	s=_s; 
    98 // 	t=_t; 
    99 // 	capacity=&_capacity;
   100 // 	flow=&_flow;
   101 // 	n=_G.nodeNum;
   102 // 	level.set (_G); //kellene vmi ilyesmi fv 
   103 // 	excess(_G,0); //itt is
   104 //       }
   105 
   106   public:
   107  
   108     ///\todo Document this
   109     enum flowEnum{
   110       ZERO_FLOW=0,
   111       GEN_FLOW=1,
   112       PREFLOW=2
   113     };
   114 
   115     MaxFlow(const Graph& _G, Node _s, Node _t, const CapMap& _capacity, 
   116 	    FlowMap& _flow) :
   117       g(&_G), s(_s), t(_t), capacity(&_capacity), 
   118       flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0) {}
   119 
   120     /// A max flow algorithm is run.
   121     ///\pre the flow have to be 0 at the beginning.
   122     void run() {
   123       preflow(ZERO_FLOW);
   124     }
   125     
   126     /// A preflow algorithm is run. 
   127     ///\pre The initial edge-map have to be a 
   128     /// zero flow if \c fe is \c ZERO_FLOW,
   129     /// a flow if \c fe is \c GEN_FLOW, 
   130     /// and a pre-flow it is \c PREFLOW.
   131     void preflow(flowEnum fe) {
   132       preflowPhase0(fe);
   133       preflowPhase1();
   134     }
   135 
   136     /// Run the first phase of preflow, starting from a 0 flow, from a flow, 
   137     /// or from a preflow, according to \c fe.
   138     void preflowPhase0( flowEnum fe );
   139 
   140     /// Second phase of preflow.
   141     void preflowPhase1();
   142 
   143     /// Starting from a flow, this method searches for an augmenting path 
   144     /// according to the Edmonds-Karp algorithm 
   145     /// and augments the flow on if any. 
   146     /// The return value shows if the augmentation was succesful.
   147     bool augmentOnShortestPath();
   148 
   149     /// Starting from a flow, this method searches for an augmenting blockin 
   150     /// flow according to Dinits' algorithm and augments the flow on if any. 
   151     /// The blocking flow is computed in a physically constructed 
   152     /// residual graph of type \c Mutablegraph.
   153     /// The return value show sif the augmentation was succesful.
   154     template<typename MutableGraph> bool augmentOnBlockingFlow();
   155 
   156     /// The same as \c augmentOnBlockingFlow<MutableGraph> but the 
   157     /// residual graph is not constructed physically.
   158     /// The return value shows if the augmentation was succesful.
   159     bool augmentOnBlockingFlow2();
   160 
   161     /// Returns the actual flow value.
   162     /// More precisely, it returns the negative excess of s, thus 
   163     /// this works also for preflows.
   164     Num flowValue() { 
   165       Num a=0;
   166       FOR_EACH_INC_LOC(OutEdgeIt, e, *g, s) a+=(*flow)[e];
   167       FOR_EACH_INC_LOC(InEdgeIt, e, *g, s) a-=(*flow)[e];
   168       return a;
   169     }
   170 
   171     /// Should be used between preflowPhase0 and preflowPhase1.
   172     ///\todo We have to make some status variable which shows the actual state 
   173     /// of the class. This enables us to determine which methods are valid 
   174     /// for MinCut computation
   175     template<typename _CutMap>
   176     void actMinCut(_CutMap& M) {
   177       NodeIt v;
   178       for(g->first(v); g->valid(v); g->next(v)) {
   179 	if ( level[v] < n ) {
   180 	  M.set(v,false);
   181 	} else {
   182 	  M.set(v,true);
   183 	}
   184       }
   185     }
   186 
   187     /// The unique inclusionwise minimum cut is computed by 
   188     /// processing a bfs from s in the residual graph.
   189     ///\pre flow have to be a max flow otherwise it will the whole node-set.
   190     template<typename _CutMap>
   191     void minMinCut(_CutMap& M) {
   192     
   193       std::queue<Node> queue;
   194       
   195       M.set(s,true);      
   196       queue.push(s);
   197 
   198       while (!queue.empty()) {
   199         Node w=queue.front();
   200 	queue.pop();
   201 
   202 	OutEdgeIt e;
   203 	for(g->first(e,w) ; g->valid(e); g->next(e)) {
   204 	  Node v=g->head(e);
   205 	  if (!M[v] && (*flow)[e] < (*capacity)[e] ) {
   206 	    queue.push(v);
   207 	    M.set(v, true);
   208 	  }
   209 	} 
   210 
   211 	InEdgeIt f;
   212 	for(g->first(f,w) ; g->valid(f); g->next(f)) {
   213 	  Node v=g->tail(f);
   214 	  if (!M[v] && (*flow)[f] > 0 ) {
   215 	    queue.push(v);
   216 	    M.set(v, true);
   217 	  }
   218 	} 
   219       }
   220     }
   221 
   222 
   223     /// The unique inclusionwise maximum cut is computed by 
   224     /// processing a reverse bfs from t in the residual graph.
   225     ///\pre flow have to be a max flow otherwise it will be empty.
   226     template<typename _CutMap>
   227     void maxMinCut(_CutMap& M) {
   228 
   229       NodeIt v;
   230       for(g->first(v) ; g->valid(v); g->next(v)) {
   231 	M.set(v, true);
   232       }
   233 
   234       std::queue<Node> queue;
   235       
   236       M.set(t,false);        
   237       queue.push(t);
   238 
   239       while (!queue.empty()) {
   240         Node w=queue.front();
   241 	queue.pop();
   242 
   243 
   244 	InEdgeIt e;
   245 	for(g->first(e,w) ; g->valid(e); g->next(e)) {
   246 	  Node v=g->tail(e);
   247 	  if (M[v] && (*flow)[e] < (*capacity)[e] ) {
   248 	    queue.push(v);
   249 	    M.set(v, false);
   250 	  }
   251 	}
   252 	
   253 	OutEdgeIt f;
   254 	for(g->first(f,w) ; g->valid(f); g->next(f)) {
   255 	  Node v=g->head(f);
   256 	  if (M[v] && (*flow)[f] > 0 ) {
   257 	    queue.push(v);
   258 	    M.set(v, false);
   259 	  }
   260 	}
   261       }
   262     }
   263 
   264 
   265     /// A minimum cut is computed.
   266     template<typename CutMap>
   267     void minCut(CutMap& M) { minMinCut(M); }
   268 
   269     ///
   270     void resetSource(Node _s) { s=_s; }
   271     ///
   272     void resetTarget(Node _t) { t=_t; }
   273    
   274     /// capacity-map is changed.
   275     void resetCap(const CapMap& _cap) { capacity=&_cap; }
   276     
   277     /// flow-map is changed. 
   278     void resetFlow(FlowMap& _flow) { flow=&_flow; }
   279 
   280 
   281   private:
   282 
   283     int push(Node w, VecStack& active) {
   284       
   285       int lev=level[w];
   286       Num exc=excess[w];
   287       int newlevel=n;       //bound on the next level of w
   288 	  
   289       OutEdgeIt e;
   290       for(g->first(e,w); g->valid(e); g->next(e)) {
   291 	    
   292 	if ( (*flow)[e] >= (*capacity)[e] ) continue; 
   293 	Node v=g->head(e);            
   294 	    
   295 	if( lev > level[v] ) { //Push is allowed now
   296 	  
   297 	  if ( excess[v]<=0 && v!=t && v!=s ) {
   298 	    int lev_v=level[v];
   299 	    active[lev_v].push(v);
   300 	  }
   301 	  
   302 	  Num cap=(*capacity)[e];
   303 	  Num flo=(*flow)[e];
   304 	  Num remcap=cap-flo;
   305 	  
   306 	  if ( remcap >= exc ) { //A nonsaturating push.
   307 	    
   308 	    flow->set(e, flo+exc);
   309 	    excess.set(v, excess[v]+exc);
   310 	    exc=0;
   311 	    break; 
   312 	    
   313 	  } else { //A saturating push.
   314 	    flow->set(e, cap);
   315 	    excess.set(v, excess[v]+remcap);
   316 	    exc-=remcap;
   317 	  }
   318 	} else if ( newlevel > level[v] ) newlevel = level[v];
   319       } //for out edges wv 
   320       
   321       if ( exc > 0 ) {	
   322 	InEdgeIt e;
   323 	for(g->first(e,w); g->valid(e); g->next(e)) {
   324 	  
   325 	  if( (*flow)[e] <= 0 ) continue; 
   326 	  Node v=g->tail(e); 
   327 	  
   328 	  if( lev > level[v] ) { //Push is allowed now
   329 	    
   330 	    if ( excess[v]<=0 && v!=t && v!=s ) {
   331 	      int lev_v=level[v];
   332 	      active[lev_v].push(v);
   333 	    }
   334 	    
   335 	    Num flo=(*flow)[e];
   336 	    
   337 	    if ( flo >= exc ) { //A nonsaturating push.
   338 	      
   339 	      flow->set(e, flo-exc);
   340 	      excess.set(v, excess[v]+exc);
   341 	      exc=0;
   342 	      break; 
   343 	    } else {  //A saturating push.
   344 	      
   345 	      excess.set(v, excess[v]+flo);
   346 	      exc-=flo;
   347 	      flow->set(e,0);
   348 	    }  
   349 	  } else if ( newlevel > level[v] ) newlevel = level[v];
   350 	} //for in edges vw
   351 	
   352       } // if w still has excess after the out edge for cycle
   353       
   354       excess.set(w, exc);
   355       
   356       return newlevel;
   357     }
   358 
   359 
   360     void preflowPreproc ( flowEnum fe, VecStack& active, 
   361 			  VecNode& level_list, NNMap& left, NNMap& right ) {
   362 
   363 			    std::queue<Node> bfs_queue;
   364       
   365 			    switch ( fe ) {
   366 			    case ZERO_FLOW: 
   367 			      {
   368 				//Reverse_bfs from t, to find the starting level.
   369 				level.set(t,0);
   370 				bfs_queue.push(t);
   371 	
   372 				while (!bfs_queue.empty()) {
   373 	    
   374 				  Node v=bfs_queue.front();	
   375 				  bfs_queue.pop();
   376 				  int l=level[v]+1;
   377 	    
   378 				  InEdgeIt e;
   379 				  for(g->first(e,v); g->valid(e); g->next(e)) {
   380 				    Node w=g->tail(e);
   381 				    if ( level[w] == n && w != s ) {
   382 				      bfs_queue.push(w);
   383 				      Node first=level_list[l];
   384 				      if ( g->valid(first) ) left.set(first,w);
   385 				      right.set(w,first);
   386 				      level_list[l]=w;
   387 				      level.set(w, l);
   388 				    }
   389 				  }
   390 				}
   391 	  
   392 				//the starting flow
   393 				OutEdgeIt e;
   394 				for(g->first(e,s); g->valid(e); g->next(e)) 
   395 				  {
   396 				    Num c=(*capacity)[e];
   397 				    if ( c <= 0 ) continue;
   398 				    Node w=g->head(e);
   399 				    if ( level[w] < n ) {	  
   400 				      if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
   401 				      flow->set(e, c); 
   402 				      excess.set(w, excess[w]+c);
   403 				    }
   404 				  }
   405 				break;
   406 			      }
   407 	
   408 			    case GEN_FLOW:
   409 			    case PREFLOW:
   410 			      {
   411 				//Reverse_bfs from t in the residual graph, 
   412 				//to find the starting level.
   413 				level.set(t,0);
   414 				bfs_queue.push(t);
   415 	  
   416 				while (!bfs_queue.empty()) {
   417 	    
   418 				  Node v=bfs_queue.front();	
   419 				  bfs_queue.pop();
   420 				  int l=level[v]+1;
   421 	    
   422 				  InEdgeIt e;
   423 				  for(g->first(e,v); g->valid(e); g->next(e)) {
   424 				    if ( (*capacity)[e] <= (*flow)[e] ) continue;
   425 				    Node w=g->tail(e);
   426 				    if ( level[w] == n && w != s ) {
   427 				      bfs_queue.push(w);
   428 				      Node first=level_list[l];
   429 				      if ( g->valid(first) ) left.set(first,w);
   430 				      right.set(w,first);
   431 				      level_list[l]=w;
   432 				      level.set(w, l);
   433 				    }
   434 				  }
   435 	    
   436 				  OutEdgeIt f;
   437 				  for(g->first(f,v); g->valid(f); g->next(f)) {
   438 				    if ( 0 >= (*flow)[f] ) continue;
   439 				    Node w=g->head(f);
   440 				    if ( level[w] == n && w != s ) {
   441 				      bfs_queue.push(w);
   442 				      Node first=level_list[l];
   443 				      if ( g->valid(first) ) left.set(first,w);
   444 				      right.set(w,first);
   445 				      level_list[l]=w;
   446 				      level.set(w, l);
   447 				    }
   448 				  }
   449 				}
   450 	  
   451 	  
   452 				//the starting flow
   453 				OutEdgeIt e;
   454 				for(g->first(e,s); g->valid(e); g->next(e)) 
   455 				  {
   456 				    Num rem=(*capacity)[e]-(*flow)[e];
   457 				    if ( rem <= 0 ) continue;
   458 				    Node w=g->head(e);
   459 				    if ( level[w] < n ) {	  
   460 				      if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
   461 				      flow->set(e, (*capacity)[e]); 
   462 				      excess.set(w, excess[w]+rem);
   463 				    }
   464 				  }
   465 	  
   466 				InEdgeIt f;
   467 				for(g->first(f,s); g->valid(f); g->next(f)) 
   468 				  {
   469 				    if ( (*flow)[f] <= 0 ) continue;
   470 				    Node w=g->tail(f);
   471 				    if ( level[w] < n ) {	  
   472 				      if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
   473 				      excess.set(w, excess[w]+(*flow)[f]);
   474 				      flow->set(f, 0); 
   475 				    }
   476 				  }  
   477 				break;
   478 			      } //case PREFLOW
   479 			    }
   480 			  } //preflowPreproc
   481 
   482 
   483 
   484     void relabel(Node w, int newlevel, VecStack& active,  
   485 		 VecNode& level_list, NNMap& left, 
   486 		 NNMap& right, int& b, int& k, bool what_heur ) 
   487     {
   488 
   489       Num lev=level[w];	
   490       
   491       Node right_n=right[w];
   492       Node left_n=left[w];
   493       
   494       //unlacing starts
   495       if ( g->valid(right_n) ) {
   496 	if ( g->valid(left_n) ) {
   497 	  right.set(left_n, right_n);
   498 	  left.set(right_n, left_n);
   499 	} else {
   500 	  level_list[lev]=right_n;   
   501 	  left.set(right_n, INVALID);
   502 	} 
   503       } else {
   504 	if ( g->valid(left_n) ) {
   505 	  right.set(left_n, INVALID);
   506 	} else { 
   507 	  level_list[lev]=INVALID;   
   508 	} 
   509       } 
   510       //unlacing ends
   511 		
   512       if ( !g->valid(level_list[lev]) ) {
   513 	      
   514 	//gapping starts
   515 	for (int i=lev; i!=k ; ) {
   516 	  Node v=level_list[++i];
   517 	  while ( g->valid(v) ) {
   518 	    level.set(v,n);
   519 	    v=right[v];
   520 	  }
   521 	  level_list[i]=INVALID;
   522 	  if ( !what_heur ) {
   523 	    while ( !active[i].empty() ) {
   524 	      active[i].pop();    //FIXME: ezt szebben kene
   525 	    }
   526 	  }	     
   527 	}
   528 	
   529 	level.set(w,n);
   530 	b=lev-1;
   531 	k=b;
   532 	//gapping ends
   533 	
   534       } else {
   535 	
   536 	if ( newlevel == n ) level.set(w,n); 
   537 	else {
   538 	  level.set(w,++newlevel);
   539 	  active[newlevel].push(w);
   540 	  if ( what_heur ) b=newlevel;
   541 	  if ( k < newlevel ) ++k;      //now k=newlevel
   542 	  Node first=level_list[newlevel];
   543 	  if ( g->valid(first) ) left.set(first,w);
   544 	  right.set(w,first);
   545 	  left.set(w,INVALID);
   546 	  level_list[newlevel]=w;
   547 	}
   548       }
   549       
   550     } //relabel
   551 
   552 
   553     template<typename MapGraphWrapper> 
   554     class DistanceMap {
   555     protected:
   556       const MapGraphWrapper* g;
   557       typename MapGraphWrapper::template NodeMap<int> dist; 
   558     public:
   559       DistanceMap(MapGraphWrapper& _g) : g(&_g), dist(*g, g->nodeNum()) { }
   560       void set(const typename MapGraphWrapper::Node& n, int a) { 
   561 	dist.set(n, a); 
   562       }
   563       int operator[](const typename MapGraphWrapper::Node& n) 
   564       { return dist[n]; }
   565       //       int get(const typename MapGraphWrapper::Node& n) const { 
   566       // 	return dist[n]; }
   567       //       bool get(const typename MapGraphWrapper::Edge& e) const { 
   568       // 	return (dist.get(g->tail(e))<dist.get(g->head(e))); }
   569       bool operator[](const typename MapGraphWrapper::Edge& e) const { 
   570 	return (dist[g->tail(e)]<dist[g->head(e)]); 
   571       }
   572     };
   573     
   574   };
   575 
   576 
   577   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
   578   void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase0( flowEnum fe ) 
   579   {
   580       
   581     int heur0=(int)(H0*n);  //time while running 'bound decrease' 
   582     int heur1=(int)(H1*n);  //time while running 'highest label'
   583     int heur=heur1;         //starting time interval (#of relabels)
   584     int numrelabel=0;
   585      
   586     bool what_heur=1;       
   587     //It is 0 in case 'bound decrease' and 1 in case 'highest label'
   588 
   589     bool end=false;     
   590     //Needed for 'bound decrease', true means no active nodes are above bound b.
   591 
   592     int k=n-2;  //bound on the highest level under n containing a node
   593     int b=k;    //bound on the highest level under n of an active node
   594       
   595     VecStack active(n);
   596       
   597     NNMap left(*g, INVALID);
   598     NNMap right(*g, INVALID);
   599     VecNode level_list(n,INVALID);
   600     //List of the nodes in level i<n, set to n.
   601 
   602     NodeIt v;
   603     for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
   604     //setting each node to level n
   605       
   606     switch ( fe ) {
   607     case PREFLOW:
   608       {
   609 	//counting the excess
   610 	NodeIt v;
   611 	for(g->first(v); g->valid(v); g->next(v)) {
   612 	  Num exc=0;
   613 	  
   614 	  InEdgeIt e;
   615 	  for(g->first(e,v); g->valid(e); g->next(e)) exc+=(*flow)[e];
   616 	  OutEdgeIt f;
   617 	  for(g->first(f,v); g->valid(f); g->next(f)) exc-=(*flow)[f];
   618 	    
   619 	  excess.set(v,exc);	  
   620 	    
   621 	  //putting the active nodes into the stack
   622 	  int lev=level[v];
   623 	  if ( exc > 0 && lev < n && v != t ) active[lev].push(v);
   624 	}
   625 	break;
   626       }
   627     case GEN_FLOW:
   628       {
   629 	//Counting the excess of t
   630 	Num exc=0;
   631 	  
   632 	InEdgeIt e;
   633 	for(g->first(e,t); g->valid(e); g->next(e)) exc+=(*flow)[e];
   634 	OutEdgeIt f;
   635 	for(g->first(f,t); g->valid(f); g->next(f)) exc-=(*flow)[f];
   636 	  
   637 	excess.set(t,exc);	
   638 	  
   639 	break;
   640       }
   641     default:
   642       break;
   643     }
   644       
   645     preflowPreproc( fe, active, level_list, left, right );
   646     //End of preprocessing 
   647       
   648       
   649     //Push/relabel on the highest level active nodes.
   650     while ( true ) {
   651       if ( b == 0 ) {
   652 	if ( !what_heur && !end && k > 0 ) {
   653 	  b=k;
   654 	  end=true;
   655 	} else break;
   656       }
   657 	
   658       if ( active[b].empty() ) --b; 
   659       else {
   660 	end=false;  
   661 	Node w=active[b].top();
   662 	active[b].pop();
   663 	int newlevel=push(w,active);
   664 	if ( excess[w] > 0 ) relabel(w, newlevel, active, level_list, 
   665 				     left, right, b, k, what_heur);
   666 	  
   667 	++numrelabel; 
   668 	if ( numrelabel >= heur ) {
   669 	  numrelabel=0;
   670 	  if ( what_heur ) {
   671 	    what_heur=0;
   672 	    heur=heur0;
   673 	    end=false;
   674 	  } else {
   675 	    what_heur=1;
   676 	    heur=heur1;
   677 	    b=k; 
   678 	  }
   679 	}
   680       } 
   681     } 
   682   }
   683 
   684 
   685 
   686   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
   687   void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase1() 
   688   {
   689       
   690     int k=n-2;  //bound on the highest level under n containing a node
   691     int b=k;    //bound on the highest level under n of an active node
   692       
   693     VecStack active(n);
   694     level.set(s,0);
   695     std::queue<Node> bfs_queue;
   696     bfs_queue.push(s);
   697 	    
   698     while (!bfs_queue.empty()) {
   699 	
   700       Node v=bfs_queue.front();	
   701       bfs_queue.pop();
   702       int l=level[v]+1;
   703 	      
   704       InEdgeIt e;
   705       for(g->first(e,v); g->valid(e); g->next(e)) {
   706 	if ( (*capacity)[e] <= (*flow)[e] ) continue;
   707 	Node u=g->tail(e);
   708 	if ( level[u] >= n ) { 
   709 	  bfs_queue.push(u);
   710 	  level.set(u, l);
   711 	  if ( excess[u] > 0 ) active[l].push(u);
   712 	}
   713       }
   714 	
   715       OutEdgeIt f;
   716       for(g->first(f,v); g->valid(f); g->next(f)) {
   717 	if ( 0 >= (*flow)[f] ) continue;
   718 	Node u=g->head(f);
   719 	if ( level[u] >= n ) { 
   720 	  bfs_queue.push(u);
   721 	  level.set(u, l);
   722 	  if ( excess[u] > 0 ) active[l].push(u);
   723 	}
   724       }
   725     }
   726     b=n-2;
   727 
   728     while ( true ) {
   729 	
   730       if ( b == 0 ) break;
   731 
   732       if ( active[b].empty() ) --b; 
   733       else {
   734 	Node w=active[b].top();
   735 	active[b].pop();
   736 	int newlevel=push(w,active);	  
   737 
   738 	//relabel
   739 	if ( excess[w] > 0 ) {
   740 	  level.set(w,++newlevel);
   741 	  active[newlevel].push(w);
   742 	  b=newlevel;
   743 	}
   744       }  // if stack[b] is nonempty
   745     } // while(true)
   746   }
   747 
   748 
   749 
   750   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
   751   bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath() 
   752   {
   753     ResGW res_graph(*g, *capacity, *flow);
   754     bool _augment=false;
   755       
   756     //ReachedMap level(res_graph);
   757     FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
   758     BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
   759     bfs.pushAndSetReached(s);
   760 	
   761     typename ResGW::template NodeMap<ResGWEdge> pred(res_graph); 
   762     pred.set(s, INVALID);
   763       
   764     typename ResGW::template NodeMap<Num> free(res_graph);
   765 	
   766     //searching for augmenting path
   767     while ( !bfs.finished() ) { 
   768       ResGWOutEdgeIt e=bfs;
   769       if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
   770 	Node v=res_graph.tail(e);
   771 	Node w=res_graph.head(e);
   772 	pred.set(w, e);
   773 	if (res_graph.valid(pred[v])) {
   774 	  free.set(w, std::min(free[v], res_graph.resCap(e)));
   775 	} else {
   776 	  free.set(w, res_graph.resCap(e)); 
   777 	}
   778 	if (res_graph.head(e)==t) { _augment=true; break; }
   779       }
   780 	
   781       ++bfs;
   782     } //end of searching augmenting path
   783 
   784     if (_augment) {
   785       Node n=t;
   786       Num augment_value=free[t];
   787       while (res_graph.valid(pred[n])) { 
   788 	ResGWEdge e=pred[n];
   789 	res_graph.augment(e, augment_value); 
   790 	n=res_graph.tail(e);
   791       }
   792     }
   793 
   794     return _augment;
   795   }
   796 
   797 
   798 
   799 
   800 
   801 
   802 
   803 
   804 
   805   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
   806   template<typename MutableGraph> 
   807   bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow() 
   808   {      
   809     typedef MutableGraph MG;
   810     bool _augment=false;
   811 
   812     ResGW res_graph(*g, *capacity, *flow);
   813 
   814     //bfs for distances on the residual graph
   815     //ReachedMap level(res_graph);
   816     FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
   817     BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
   818     bfs.pushAndSetReached(s);
   819     typename ResGW::template NodeMap<int> 
   820       dist(res_graph); //filled up with 0's
   821 
   822     //F will contain the physical copy of the residual graph
   823     //with the set of edges which are on shortest paths
   824     MG F;
   825     typename ResGW::template NodeMap<typename MG::Node> 
   826       res_graph_to_F(res_graph);
   827     {
   828       typename ResGW::NodeIt n;
   829       for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
   830 	res_graph_to_F.set(n, F.addNode());
   831       }
   832     }
   833 
   834     typename MG::Node sF=res_graph_to_F[s];
   835     typename MG::Node tF=res_graph_to_F[t];
   836     typename MG::template EdgeMap<ResGWEdge> original_edge(F);
   837     typename MG::template EdgeMap<Num> residual_capacity(F);
   838 
   839     while ( !bfs.finished() ) { 
   840       ResGWOutEdgeIt e=bfs;
   841       if (res_graph.valid(e)) {
   842 	if (bfs.isBNodeNewlyReached()) {
   843 	  dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
   844 	  typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
   845 	  original_edge.update();
   846 	  original_edge.set(f, e);
   847 	  residual_capacity.update();
   848 	  residual_capacity.set(f, res_graph.resCap(e));
   849 	} else {
   850 	  if (dist[res_graph.head(e)]==(dist[res_graph.tail(e)]+1)) {
   851 	    typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
   852 	    original_edge.update();
   853 	    original_edge.set(f, e);
   854 	    residual_capacity.update();
   855 	    residual_capacity.set(f, res_graph.resCap(e));
   856 	  }
   857 	}
   858       }
   859       ++bfs;
   860     } //computing distances from s in the residual graph
   861 
   862     bool __augment=true;
   863 
   864     while (__augment) {
   865       __augment=false;
   866       //computing blocking flow with dfs
   867       DfsIterator< MG, typename MG::template NodeMap<bool> > dfs(F);
   868       typename MG::template NodeMap<typename MG::Edge> pred(F);
   869       pred.set(sF, INVALID);
   870       //invalid iterators for sources
   871 
   872       typename MG::template NodeMap<Num> free(F);
   873 
   874       dfs.pushAndSetReached(sF);      
   875       while (!dfs.finished()) {
   876 	++dfs;
   877 	if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
   878 	  if (dfs.isBNodeNewlyReached()) {
   879 	    typename MG::Node v=F.aNode(dfs);
   880 	    typename MG::Node w=F.bNode(dfs);
   881 	    pred.set(w, dfs);
   882 	    if (F.valid(pred[v])) {
   883 	      free.set(w, std::min(free[v], residual_capacity[dfs]));
   884 	    } else {
   885 	      free.set(w, residual_capacity[dfs]); 
   886 	    }
   887 	    if (w==tF) { 
   888 	      __augment=true; 
   889 	      _augment=true;
   890 	      break; 
   891 	    }
   892 	      
   893 	  } else {
   894 	    F.erase(/*typename MG::OutEdgeIt*/(dfs));
   895 	  }
   896 	} 
   897       }
   898 
   899       if (__augment) {
   900 	typename MG::Node n=tF;
   901 	Num augment_value=free[tF];
   902 	while (F.valid(pred[n])) { 
   903 	  typename MG::Edge e=pred[n];
   904 	  res_graph.augment(original_edge[e], augment_value); 
   905 	  n=F.tail(e);
   906 	  if (residual_capacity[e]==augment_value) 
   907 	    F.erase(e); 
   908 	  else 
   909 	    residual_capacity.set(e, residual_capacity[e]-augment_value);
   910 	}
   911       }
   912 	
   913     }
   914             
   915     return _augment;
   916   }
   917 
   918 
   919 
   920 
   921 
   922 
   923   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
   924   bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow2() 
   925   {
   926     bool _augment=false;
   927 
   928     ResGW res_graph(*g, *capacity, *flow);
   929       
   930     //ReachedMap level(res_graph);
   931     FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
   932     BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
   933 
   934     bfs.pushAndSetReached(s);
   935     DistanceMap<ResGW> dist(res_graph);
   936     while ( !bfs.finished() ) { 
   937       ResGWOutEdgeIt e=bfs;
   938       if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
   939 	dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
   940       }
   941       ++bfs;
   942     } //computing distances from s in the residual graph
   943 
   944       //Subgraph containing the edges on some shortest paths
   945     ConstMap<typename ResGW::Node, bool> true_map(true);
   946     typedef SubGraphWrapper<ResGW, ConstMap<typename ResGW::Node, bool>, 
   947       DistanceMap<ResGW> > FilterResGW;
   948     FilterResGW filter_res_graph(res_graph, true_map, dist);
   949 
   950     //Subgraph, which is able to delete edges which are already 
   951     //met by the dfs
   952     typename FilterResGW::template NodeMap<typename FilterResGW::OutEdgeIt> 
   953       first_out_edges(filter_res_graph);
   954     typename FilterResGW::NodeIt v;
   955     for(filter_res_graph.first(v); filter_res_graph.valid(v); 
   956 	filter_res_graph.next(v)) 
   957       {
   958  	typename FilterResGW::OutEdgeIt e;
   959  	filter_res_graph.first(e, v);
   960  	first_out_edges.set(v, e);
   961       }
   962     typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
   963       template NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
   964     ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
   965 
   966     bool __augment=true;
   967 
   968     while (__augment) {
   969 
   970       __augment=false;
   971       //computing blocking flow with dfs
   972       DfsIterator< ErasingResGW, 
   973 	typename ErasingResGW::template NodeMap<bool> > 
   974 	dfs(erasing_res_graph);
   975       typename ErasingResGW::
   976 	template NodeMap<typename ErasingResGW::OutEdgeIt> 
   977 	pred(erasing_res_graph); 
   978       pred.set(s, INVALID);
   979       //invalid iterators for sources
   980 
   981       typename ErasingResGW::template NodeMap<Num> 
   982 	free1(erasing_res_graph);
   983 
   984       dfs.pushAndSetReached(
   985 			    typename ErasingResGW::Node(
   986 							typename FilterResGW::Node(
   987 										   typename ResGW::Node(s)
   988 										   )
   989 							)
   990 			    );
   991       while (!dfs.finished()) {
   992 	++dfs;
   993 	if (erasing_res_graph.valid(
   994 				    typename ErasingResGW::OutEdgeIt(dfs))) 
   995  	  { 
   996   	    if (dfs.isBNodeNewlyReached()) {
   997 	  
   998  	      typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs);
   999  	      typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs);
  1000 
  1001  	      pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs));
  1002  	      if (erasing_res_graph.valid(pred[v])) {
  1003  		free1.set(w, std::min(free1[v], res_graph.resCap(
  1004 								 typename ErasingResGW::OutEdgeIt(dfs))));
  1005  	      } else {
  1006  		free1.set(w, res_graph.resCap(
  1007 					      typename ErasingResGW::OutEdgeIt(dfs))); 
  1008  	      }
  1009 	      
  1010  	      if (w==t) { 
  1011  		__augment=true; 
  1012  		_augment=true;
  1013  		break; 
  1014  	      }
  1015  	    } else {
  1016  	      erasing_res_graph.erase(dfs);
  1017 	    }
  1018 	  }
  1019       }	
  1020 
  1021       if (__augment) {
  1022 	typename ErasingResGW::Node n=typename FilterResGW::Node(typename ResGW::Node(t));
  1023 	// 	  typename ResGW::NodeMap<Num> a(res_graph);
  1024 	// 	  typename ResGW::Node b;
  1025 	// 	  Num j=a[b];
  1026 	// 	  typename FilterResGW::NodeMap<Num> a1(filter_res_graph);
  1027 	// 	  typename FilterResGW::Node b1;
  1028 	// 	  Num j1=a1[b1];
  1029 	// 	  typename ErasingResGW::NodeMap<Num> a2(erasing_res_graph);
  1030 	// 	  typename ErasingResGW::Node b2;
  1031 	// 	  Num j2=a2[b2];
  1032 	Num augment_value=free1[n];
  1033 	while (erasing_res_graph.valid(pred[n])) { 
  1034 	  typename ErasingResGW::OutEdgeIt e=pred[n];
  1035 	  res_graph.augment(e, augment_value);
  1036 	  n=erasing_res_graph.tail(e);
  1037 	  if (res_graph.resCap(e)==0)
  1038 	    erasing_res_graph.erase(e);
  1039 	}
  1040       }
  1041       
  1042     } //while (__augment) 
  1043             
  1044     return _augment;
  1045   }
  1046 
  1047 
  1048 
  1049 
  1050 } //namespace hugo
  1051 
  1052 #endif //HUGO_MAX_FLOW_H
  1053 
  1054 
  1055 
  1056