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