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