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