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