src/work/jacint/preflow.h
author marci
Thu, 29 Apr 2004 15:01:52 +0000
changeset 471 a40985a922d0
parent 470 b64956c701c9
child 472 052af4060f3e
permissions -rw-r--r--
misc
     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_PREFLOW_H
    37 #define HUGO_PREFLOW_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 
    48 namespace hugo {
    49 
    50   template <typename Graph, typename Num, 
    51 	    typename CapMap=typename Graph::template EdgeMap<Num>, 
    52             typename FlowMap=typename Graph::template EdgeMap<Num> >
    53   class Preflow {
    54     
    55     typedef typename Graph::Node Node;
    56     typedef typename Graph::NodeIt NodeIt;
    57     typedef typename Graph::OutEdgeIt OutEdgeIt;
    58     typedef typename Graph::InEdgeIt InEdgeIt;
    59 
    60     typedef typename std::vector<std::stack<Node> > VecStack;
    61     typedef typename Graph::template NodeMap<Node> NNMap;
    62     typedef typename std::vector<Node> VecNode;
    63 
    64     const Graph* g;
    65     Node s;
    66     Node t;
    67     const CapMap* capacity;  
    68     FlowMap* flow;
    69     int n;      //the number of nodes of G
    70     typedef ResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;
    71     typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
    72     typedef typename ResGW::Edge ResGWEdge;
    73     //typedef typename ResGW::template NodeMap<bool> ReachedMap;
    74     typedef typename Graph::template NodeMap<int> ReachedMap;
    75     ReachedMap level;
    76     //level works as a bool map in augmenting path algorithms 
    77     //and is used by bfs for storing reached information.
    78     //In preflow, it shows levels of nodes.
    79     //typename Graph::template NodeMap<int> level;    
    80     typename Graph::template NodeMap<Num> excess; 
    81 
    82   public:
    83  
    84     enum flowEnum{
    85       ZERO_FLOW=0,
    86       GEN_FLOW=1,
    87       PREFLOW=2
    88     };
    89 
    90     Preflow(const Graph& _G, Node _s, Node _t, const CapMap& _capacity, 
    91 	    FlowMap& _flow) :
    92       g(&_G), s(_s), t(_t), capacity(&_capacity), 
    93       flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0) {}
    94 
    95     void run() {
    96       preflow( ZERO_FLOW );
    97     }
    98     
    99     void preflow( flowEnum fe ) {
   100       preflowPhase0(fe);
   101       preflowPhase1();
   102     }
   103 
   104     void preflowPhase0( flowEnum fe );
   105 
   106     void preflowPhase1();
   107 
   108     bool augmentOnShortestPath();
   109 
   110     template<typename MutableGraph> bool augmentOnBlockingFlow();
   111 
   112     bool augmentOnBlockingFlow2();
   113 
   114     //Returns the maximum value of a flow.
   115     Num flowValue() {
   116       return excess[t];
   117     }
   118 
   119     //should be used only between preflowPhase0 and preflowPhase1
   120     template<typename _CutMap>
   121     void actMinCut(_CutMap& M) {
   122       NodeIt v;
   123       for(g->first(v); g->valid(v); g->next(v)) 
   124       if ( level[v] < n ) {
   125 	M.set(v,false);
   126       } else {
   127 	M.set(v,true);
   128       }
   129     }
   130 
   131 
   132 
   133     /*
   134       Returns the minimum min cut, by a bfs from s in the residual graph.
   135     */
   136     template<typename _CutMap>
   137     void minMinCut(_CutMap& M) {
   138     
   139       std::queue<Node> queue;
   140       
   141       M.set(s,true);      
   142       queue.push(s);
   143 
   144       while (!queue.empty()) {
   145         Node w=queue.front();
   146 	queue.pop();
   147 
   148 	OutEdgeIt e;
   149 	for(g->first(e,w) ; g->valid(e); g->next(e)) {
   150 	  Node v=g->head(e);
   151 	  if (!M[v] && (*flow)[e] < (*capacity)[e] ) {
   152 	    queue.push(v);
   153 	    M.set(v, true);
   154 	  }
   155 	} 
   156 
   157 	InEdgeIt f;
   158 	for(g->first(f,w) ; g->valid(f); g->next(f)) {
   159 	  Node v=g->tail(f);
   160 	  if (!M[v] && (*flow)[f] > 0 ) {
   161 	    queue.push(v);
   162 	    M.set(v, true);
   163 	  }
   164 	} 
   165       }
   166     }
   167 
   168 
   169   
   170     /*
   171       Returns the maximum min cut, by a reverse bfs 
   172       from t in the residual graph.
   173     */
   174     
   175     template<typename _CutMap>
   176     void maxMinCut(_CutMap& M) {
   177 
   178       NodeIt v;
   179       for(g->first(v) ; g->valid(v); g->next(v)) {
   180 	M.set(v, true);
   181       }
   182 
   183       std::queue<Node> queue;
   184       
   185       M.set(t,false);        
   186       queue.push(t);
   187 
   188       while (!queue.empty()) {
   189         Node w=queue.front();
   190 	queue.pop();
   191 
   192 
   193 	InEdgeIt e;
   194 	for(g->first(e,w) ; g->valid(e); g->next(e)) {
   195 	  Node v=g->tail(e);
   196 	  if (M[v] && (*flow)[e] < (*capacity)[e] ) {
   197 	    queue.push(v);
   198 	    M.set(v, false);
   199 	  }
   200 	}
   201 	
   202 	OutEdgeIt f;
   203 	for(g->first(f,w) ; g->valid(f); g->next(f)) {
   204 	  Node v=g->head(f);
   205 	  if (M[v] && (*flow)[f] > 0 ) {
   206 	    queue.push(v);
   207 	    M.set(v, false);
   208 	  }
   209 	}
   210       }
   211     }
   212 
   213 
   214     template<typename CutMap>
   215     void minCut(CutMap& M) {
   216       minMinCut(M);
   217     }
   218 
   219     void resetTarget(Node _t) {t=_t;}
   220     void resetSource(Node _s) {s=_s;}
   221    
   222     void resetCap(const CapMap& _cap) {
   223       capacity=&_cap;
   224     }
   225     
   226     void resetFlow(FlowMap& _flow) {
   227       flow=&_flow;
   228     }
   229 
   230 
   231   private:
   232 
   233     int push(Node w, VecStack& active) {
   234       
   235       int lev=level[w];
   236       Num exc=excess[w];
   237       int newlevel=n;       //bound on the next level of w
   238 	  
   239       OutEdgeIt e;
   240       for(g->first(e,w); g->valid(e); g->next(e)) {
   241 	    
   242 	if ( (*flow)[e] >= (*capacity)[e] ) continue; 
   243 	Node v=g->head(e);            
   244 	    
   245 	if( lev > level[v] ) { //Push is allowed now
   246 	  
   247 	  if ( excess[v]<=0 && v!=t && v!=s ) {
   248 	    int lev_v=level[v];
   249 	    active[lev_v].push(v);
   250 	  }
   251 	  
   252 	  Num cap=(*capacity)[e];
   253 	  Num flo=(*flow)[e];
   254 	  Num remcap=cap-flo;
   255 	  
   256 	  if ( remcap >= exc ) { //A nonsaturating push.
   257 	    
   258 	    flow->set(e, flo+exc);
   259 	    excess.set(v, excess[v]+exc);
   260 	    exc=0;
   261 	    break; 
   262 	    
   263 	  } else { //A saturating push.
   264 	    flow->set(e, cap);
   265 	    excess.set(v, excess[v]+remcap);
   266 	    exc-=remcap;
   267 	  }
   268 	} else if ( newlevel > level[v] ) newlevel = level[v];
   269       } //for out edges wv 
   270       
   271       if ( exc > 0 ) {	
   272 	InEdgeIt e;
   273 	for(g->first(e,w); g->valid(e); g->next(e)) {
   274 	  
   275 	  if( (*flow)[e] <= 0 ) continue; 
   276 	  Node v=g->tail(e); 
   277 	  
   278 	  if( lev > level[v] ) { //Push is allowed now
   279 	    
   280 	    if ( excess[v]<=0 && v!=t && v!=s ) {
   281 	      int lev_v=level[v];
   282 	      active[lev_v].push(v);
   283 	    }
   284 	    
   285 	    Num flo=(*flow)[e];
   286 	    
   287 	    if ( flo >= exc ) { //A nonsaturating push.
   288 	      
   289 	      flow->set(e, flo-exc);
   290 	      excess.set(v, excess[v]+exc);
   291 	      exc=0;
   292 	      break; 
   293 	    } else {  //A saturating push.
   294 	      
   295 	      excess.set(v, excess[v]+flo);
   296 	      exc-=flo;
   297 	      flow->set(e,0);
   298 	    }  
   299 	  } else if ( newlevel > level[v] ) newlevel = level[v];
   300 	} //for in edges vw
   301 	
   302       } // if w still has excess after the out edge for cycle
   303       
   304       excess.set(w, exc);
   305       
   306       return newlevel;
   307      }
   308 
   309 
   310     void preflowPreproc ( flowEnum fe, VecStack& active, 
   311 			  VecNode& level_list, NNMap& left, NNMap& right ) {
   312 
   313       std::queue<Node> bfs_queue;
   314       
   315       switch ( fe ) {
   316       case ZERO_FLOW: 
   317 	{
   318 	  //Reverse_bfs from t, to find the starting level.
   319 	  level.set(t,0);
   320 	  bfs_queue.push(t);
   321 	
   322 	  while (!bfs_queue.empty()) {
   323 	    
   324 	    Node v=bfs_queue.front();	
   325 	    bfs_queue.pop();
   326 	    int l=level[v]+1;
   327 	    
   328 	    InEdgeIt e;
   329 	    for(g->first(e,v); g->valid(e); g->next(e)) {
   330 	      Node w=g->tail(e);
   331 	      if ( level[w] == n && w != s ) {
   332 		bfs_queue.push(w);
   333 		Node first=level_list[l];
   334 		if ( g->valid(first) ) left.set(first,w);
   335 		right.set(w,first);
   336 		level_list[l]=w;
   337 		level.set(w, l);
   338 	      }
   339 	    }
   340 	  }
   341 	  
   342 	  //the starting flow
   343 	  OutEdgeIt e;
   344 	  for(g->first(e,s); g->valid(e); g->next(e)) 
   345 	    {
   346 	      Num c=(*capacity)[e];
   347 	      if ( c <= 0 ) continue;
   348 	      Node w=g->head(e);
   349 	      if ( level[w] < n ) {	  
   350 		if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
   351 		flow->set(e, c); 
   352 		excess.set(w, excess[w]+c);
   353 	      }
   354 	    }
   355 	  break;
   356 	}
   357 	
   358       case GEN_FLOW:
   359       case PREFLOW:
   360 	{
   361 	  //Reverse_bfs from t in the residual graph, 
   362 	  //to find the starting level.
   363 	  level.set(t,0);
   364 	  bfs_queue.push(t);
   365 	  
   366 	  while (!bfs_queue.empty()) {
   367 	    
   368 	    Node v=bfs_queue.front();	
   369 	    bfs_queue.pop();
   370 	    int l=level[v]+1;
   371 	    
   372 	    InEdgeIt e;
   373 	    for(g->first(e,v); g->valid(e); g->next(e)) {
   374 	      if ( (*capacity)[e] <= (*flow)[e] ) continue;
   375 	      Node w=g->tail(e);
   376 	      if ( level[w] == n && w != s ) {
   377 		bfs_queue.push(w);
   378 		Node first=level_list[l];
   379 		if ( g->valid(first) ) left.set(first,w);
   380 		right.set(w,first);
   381 		level_list[l]=w;
   382 		level.set(w, l);
   383 	      }
   384 	    }
   385 	    
   386 	    OutEdgeIt f;
   387 	    for(g->first(f,v); g->valid(f); g->next(f)) {
   388 	      if ( 0 >= (*flow)[f] ) continue;
   389 	      Node w=g->head(f);
   390 	      if ( level[w] == n && w != s ) {
   391 		bfs_queue.push(w);
   392 		Node first=level_list[l];
   393 		if ( g->valid(first) ) left.set(first,w);
   394 		right.set(w,first);
   395 		level_list[l]=w;
   396 		level.set(w, l);
   397 	      }
   398 	    }
   399 	  }
   400 	  
   401 	  
   402 	  //the starting flow
   403 	  OutEdgeIt e;
   404 	  for(g->first(e,s); g->valid(e); g->next(e)) 
   405 	    {
   406 	      Num rem=(*capacity)[e]-(*flow)[e];
   407 	      if ( rem <= 0 ) continue;
   408 	      Node w=g->head(e);
   409 	      if ( level[w] < n ) {	  
   410 		if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
   411 		flow->set(e, (*capacity)[e]); 
   412 		excess.set(w, excess[w]+rem);
   413 	      }
   414 	    }
   415 	  
   416 	  InEdgeIt f;
   417 	  for(g->first(f,s); g->valid(f); g->next(f)) 
   418 	    {
   419 	      if ( (*flow)[f] <= 0 ) continue;
   420 	      Node w=g->tail(f);
   421 	      if ( level[w] < n ) {	  
   422 		if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
   423 		excess.set(w, excess[w]+(*flow)[f]);
   424 		flow->set(f, 0); 
   425 	      }
   426 	    }  
   427 	  break;
   428 	} //case PREFLOW
   429       }
   430     } //preflowPreproc
   431 
   432 
   433 
   434     void relabel(Node w, int newlevel, VecStack& active,  
   435 		 VecNode& level_list, NNMap& left, 
   436 		 NNMap& right, int& b, int& k, bool what_heur ) {
   437 
   438       Num lev=level[w];	
   439       
   440       Node right_n=right[w];
   441       Node left_n=left[w];
   442       
   443       //unlacing starts
   444       if ( g->valid(right_n) ) {
   445 	if ( g->valid(left_n) ) {
   446 	  right.set(left_n, right_n);
   447 	  left.set(right_n, left_n);
   448 	} else {
   449 	  level_list[lev]=right_n;   
   450 	  left.set(right_n, INVALID);
   451 	} 
   452       } else {
   453 	if ( g->valid(left_n) ) {
   454 	  right.set(left_n, INVALID);
   455 	} else { 
   456 	  level_list[lev]=INVALID;   
   457 	} 
   458       } 
   459       //unlacing ends
   460 		
   461       if ( !g->valid(level_list[lev]) ) {
   462 	      
   463 	//gapping starts
   464 	for (int i=lev; i!=k ; ) {
   465 	  Node v=level_list[++i];
   466 	  while ( g->valid(v) ) {
   467 	    level.set(v,n);
   468 	    v=right[v];
   469 	  }
   470 	  level_list[i]=INVALID;
   471 	  if ( !what_heur ) {
   472 	    while ( !active[i].empty() ) {
   473 	      active[i].pop();    //FIXME: ezt szebben kene
   474 	    }
   475 	  }	     
   476 	}
   477 	
   478 	level.set(w,n);
   479 	b=lev-1;
   480 	k=b;
   481 	//gapping ends
   482 	
   483       } else {
   484 	
   485 	if ( newlevel == n ) level.set(w,n); 
   486 	else {
   487 	  level.set(w,++newlevel);
   488 	  active[newlevel].push(w);
   489 	  if ( what_heur ) b=newlevel;
   490 	  if ( k < newlevel ) ++k;      //now k=newlevel
   491 	  Node first=level_list[newlevel];
   492 	  if ( g->valid(first) ) left.set(first,w);
   493 	  right.set(w,first);
   494 	  left.set(w,INVALID);
   495 	  level_list[newlevel]=w;
   496 	}
   497       }
   498       
   499     } //relabel
   500     
   501   };
   502 
   503 
   504   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
   505   void Preflow<Graph, Num, CapMap, FlowMap>::preflowPhase0( flowEnum fe ) 
   506   {
   507       
   508       int heur0=(int)(H0*n);  //time while running 'bound decrease' 
   509       int heur1=(int)(H1*n);  //time while running 'highest label'
   510       int heur=heur1;         //starting time interval (#of relabels)
   511       int numrelabel=0;
   512      
   513       bool what_heur=1;       
   514       //It is 0 in case 'bound decrease' and 1 in case 'highest label'
   515 
   516       bool end=false;     
   517       //Needed for 'bound decrease', true means no active nodes are above bound b.
   518 
   519       int k=n-2;  //bound on the highest level under n containing a node
   520       int b=k;    //bound on the highest level under n of an active node
   521       
   522       VecStack active(n);
   523       
   524       NNMap left(*g, INVALID);
   525       NNMap right(*g, INVALID);
   526       VecNode level_list(n,INVALID);
   527       //List of the nodes in level i<n, set to n.
   528 
   529       NodeIt v;
   530       for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
   531       //setting each node to level n
   532       
   533       switch ( fe ) {
   534       case PREFLOW:
   535 	{
   536 	  //counting the excess
   537 	  NodeIt v;
   538 	  for(g->first(v); g->valid(v); g->next(v)) {
   539 	    Num exc=0;
   540 	  
   541 	    InEdgeIt e;
   542 	    for(g->first(e,v); g->valid(e); g->next(e)) exc+=(*flow)[e];
   543 	    OutEdgeIt f;
   544 	    for(g->first(f,v); g->valid(f); g->next(f)) exc-=(*flow)[f];
   545 	    
   546 	    excess.set(v,exc);	  
   547 	    
   548 	    //putting the active nodes into the stack
   549 	    int lev=level[v];
   550 	    if ( exc > 0 && lev < n && v != t ) active[lev].push(v);
   551 	  }
   552 	  break;
   553 	}
   554       case GEN_FLOW:
   555 	{
   556 	  //Counting the excess of t
   557 	  Num exc=0;
   558 	  
   559 	  InEdgeIt e;
   560 	  for(g->first(e,t); g->valid(e); g->next(e)) exc+=(*flow)[e];
   561 	  OutEdgeIt f;
   562 	  for(g->first(f,t); g->valid(f); g->next(f)) exc-=(*flow)[f];
   563 	  
   564 	  excess.set(t,exc);	
   565 	  
   566 	  break;
   567 	}
   568       default:
   569 	break;
   570       }
   571       
   572       preflowPreproc( fe, active, level_list, left, right );
   573       //End of preprocessing 
   574       
   575       
   576       //Push/relabel on the highest level active nodes.
   577       while ( true ) {
   578 	if ( b == 0 ) {
   579 	  if ( !what_heur && !end && k > 0 ) {
   580 	    b=k;
   581 	    end=true;
   582 	  } else break;
   583 	}
   584 	
   585 	if ( active[b].empty() ) --b; 
   586 	else {
   587 	  end=false;  
   588 	  Node w=active[b].top();
   589 	  active[b].pop();
   590 	  int newlevel=push(w,active);
   591 	  if ( excess[w] > 0 ) relabel(w, newlevel, active, level_list, 
   592 				       left, right, b, k, what_heur);
   593 	  
   594 	  ++numrelabel; 
   595 	  if ( numrelabel >= heur ) {
   596 	    numrelabel=0;
   597 	    if ( what_heur ) {
   598 	      what_heur=0;
   599 	      heur=heur0;
   600 	      end=false;
   601 	    } else {
   602 	      what_heur=1;
   603 	      heur=heur1;
   604 	      b=k; 
   605 	    }
   606 	  }
   607 	} 
   608       } 
   609     }
   610 
   611 
   612 
   613   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
   614   void Preflow<Graph, Num, CapMap, FlowMap>::preflowPhase1() 
   615   {
   616       
   617       int k=n-2;  //bound on the highest level under n containing a node
   618       int b=k;    //bound on the highest level under n of an active node
   619       
   620       VecStack active(n);
   621       level.set(s,0);
   622       std::queue<Node> bfs_queue;
   623       bfs_queue.push(s);
   624 	    
   625       while (!bfs_queue.empty()) {
   626 	
   627 	Node v=bfs_queue.front();	
   628 	bfs_queue.pop();
   629 	int l=level[v]+1;
   630 	      
   631 	InEdgeIt e;
   632 	for(g->first(e,v); g->valid(e); g->next(e)) {
   633 	  if ( (*capacity)[e] <= (*flow)[e] ) continue;
   634 	  Node u=g->tail(e);
   635 	  if ( level[u] >= n ) { 
   636 	    bfs_queue.push(u);
   637 	    level.set(u, l);
   638 	    if ( excess[u] > 0 ) active[l].push(u);
   639 	  }
   640 	}
   641 	
   642 	OutEdgeIt f;
   643 	for(g->first(f,v); g->valid(f); g->next(f)) {
   644 	  if ( 0 >= (*flow)[f] ) continue;
   645 	  Node u=g->head(f);
   646 	  if ( level[u] >= n ) { 
   647 	    bfs_queue.push(u);
   648 	    level.set(u, l);
   649 	    if ( excess[u] > 0 ) active[l].push(u);
   650 	  }
   651 	}
   652       }
   653       b=n-2;
   654 
   655       while ( true ) {
   656 	
   657 	if ( b == 0 ) break;
   658 
   659 	if ( active[b].empty() ) --b; 
   660 	else {
   661 	  Node w=active[b].top();
   662 	  active[b].pop();
   663 	  int newlevel=push(w,active);	  
   664 
   665 	  //relabel
   666 	  if ( excess[w] > 0 ) {
   667 	    level.set(w,++newlevel);
   668 	    active[newlevel].push(w);
   669 	    b=newlevel;
   670 	  }
   671 	}  // if stack[b] is nonempty
   672       } // while(true)
   673     }
   674 
   675 
   676 
   677 
   678 
   679 
   680 
   681 
   682 
   683 
   684 
   685 
   686 } //namespace hugo
   687 
   688 #endif //HUGO_PREFLOW_H
   689 
   690 
   691 
   692