src/work/jacint/preflow_push_hl.h
author marci
Wed, 18 Feb 2004 15:58:28 +0000
changeset 99 f26897fb91fd
parent 88 93bb934b0794
child 101 d2ac583ed195
permissions -rw-r--r--
dfs iterator: DfsIterator4 improved version
     1 // -*- C++ -*-
     2 /*
     3 preflow_push_hl.h
     4 by jacint. 
     5 Runs the highest label variant of the preflow push algorithm with 
     6 running time O(n^2\sqrt(m)), and with the 'empty level' heuristic. 
     7 
     8 'A' is a parameter for the empty_level heuristic
     9 
    10 Member functions:
    11 
    12 void run() : runs the algorithm
    13 
    14  The following functions should be used after run() was already run.
    15 
    16 T maxflow() : returns the value of a maximum flow
    17 
    18 T flowonedge(EdgeIt e) : for a fixed maximum flow x it returns x(e) 
    19 
    20 FlowMap allflow() : returns the fixed maximum flow x
    21 
    22 void mincut(CutMap& M) : sets M to the characteristic vector of a 
    23      minimum cut. M should be a map of bools initialized to false.
    24 
    25 void min_mincut(CutMap& M) : sets M to the characteristic vector of the 
    26      minimum min cut. M should be a map of bools initialized to false.
    27 
    28 void max_mincut(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 */
    32 
    33 #ifndef PREFLOW_PUSH_HL_H
    34 #define PREFLOW_PUSH_HL_H
    35 
    36 #define A 1
    37 
    38 #include <vector>
    39 #include <stack>
    40 #include <queue>
    41 
    42 namespace marci {
    43 
    44   template <typename Graph, typename T, 
    45     typename FlowMap=typename Graph::EdgeMap<T>, typename CapMap=typename Graph::EdgeMap<T>, 
    46     typename IntMap=typename Graph::NodeMap<int>, typename TMap=typename Graph::NodeMap<T> >
    47   class preflow_push_hl {
    48     
    49     typedef typename Graph::NodeIt NodeIt;
    50     typedef typename Graph::EdgeIt EdgeIt;
    51     typedef typename Graph::EachNodeIt EachNodeIt;
    52     typedef typename Graph::OutEdgeIt OutEdgeIt;
    53     typedef typename Graph::InEdgeIt InEdgeIt;
    54     
    55     Graph& G;
    56     NodeIt s;
    57     NodeIt t;
    58     FlowMap flow;
    59     CapMap& capacity;  
    60     T value;
    61     
    62   public:
    63 
    64     preflow_push_hl(Graph& _G, NodeIt _s, NodeIt _t, CapMap& _capacity) :
    65       G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity) { }
    66 
    67 
    68     
    69 
    70     void run() {
    71  
    72       int n=G.nodeNum(); 
    73       int b=n-2; 
    74       /*
    75 	b is a bound on the highest level of an active node. 
    76       */
    77 
    78       IntMap level(G,n);      
    79       TMap excess(G); 
    80 
    81       std::vector<int> numb(n);    
    82       /*
    83 	The number of nodes on level i < n. It is
    84 	initialized to n+1, because of the reverse_bfs-part.
    85       */
    86 
    87       std::vector<std::stack<NodeIt> > stack(2*n-1);    
    88       //Stack of the active nodes in level i.
    89 
    90 
    91       /*Reverse_bfs from t, to find the starting level.*/
    92       level.set(t,0);
    93       std::queue<NodeIt> bfs_queue;
    94       bfs_queue.push(t);
    95 
    96       while (!bfs_queue.empty()) {
    97 
    98 	NodeIt v=bfs_queue.front();	
    99 	bfs_queue.pop();
   100 	int l=level.get(v)+1;
   101 
   102 	for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
   103 	  NodeIt w=G.tail(e);
   104 	  if ( level.get(w) == n ) {
   105 	    bfs_queue.push(w);
   106 	    ++numb[l];
   107 	    level.set(w, l);
   108 	  }
   109 	}
   110       }
   111 	
   112       level.set(s,n);
   113 
   114 
   115 
   116       /* Starting flow. It is everywhere 0 at the moment. */     
   117       for(OutEdgeIt e=G.template first<OutEdgeIt>(s); e.valid(); ++e) 
   118 	{
   119 	  if ( capacity.get(e) == 0 ) continue;
   120 	  NodeIt w=G.head(e);
   121 	  if ( w!=s ) {	  
   122 	    if ( excess.get(w) == 0 && w!=t ) stack[level.get(w)].push(w); 
   123 	    flow.set(e, capacity.get(e)); 
   124 	    excess.set(w, excess.get(w)+capacity.get(e));
   125 	  }
   126 	}
   127       
   128       /* 
   129 	 End of preprocessing 
   130       */
   131 
   132 
   133       /*
   134 	Push/relabel on the highest level active nodes.
   135       */
   136       /*While there exists an active node.*/
   137       while (b) { 
   138 	if ( stack[b].empty() ) { 
   139 	  --b;
   140 	  continue;
   141 	} 
   142 	
   143 	NodeIt w=stack[b].top();        //w is a highest label active node.
   144 	stack[b].pop();           
   145 	int lev=level.get(w);
   146 	int exc=excess.get(w);
   147 	int newlevel=2*n-2;      //In newlevel we bound the next level of w.
   148 	
   149 	//  if ( level.get(w) < n ) { //Nem tudom ez mukodik-e
   150 	  for(OutEdgeIt e=G.template first<OutEdgeIt>(w); e.valid(); ++e) {
   151 	    
   152 	    if ( flow.get(e) == capacity.get(e) ) continue; 
   153 	    NodeIt v=G.head(e);            
   154 	    //e=wv	    
   155 	    
   156 	    if( lev > level.get(v) ) {      
   157 	      /*Push is allowed now*/
   158 	      
   159 	      if ( excess.get(v)==0 && v != s && v !=t ) 
   160 		stack[level.get(v)].push(v); 
   161 	      /*v becomes active.*/
   162 	      
   163 	      int cap=capacity.get(e);
   164 	      int flo=flow.get(e);
   165 	      int remcap=cap-flo;
   166 	      
   167 	      if ( remcap >= exc ) {       
   168 		/*A nonsaturating push.*/
   169 		
   170 		flow.set(e, flo+exc);
   171 		excess.set(v, excess.get(v)+exc);
   172 		exc=0;
   173 		break; 
   174 		
   175 	      } else { 
   176 		/*A saturating push.*/
   177 		
   178 		flow.set(e, cap );
   179 		excess.set(v, excess.get(v)+remcap);
   180 		exc-=remcap;
   181 	      }
   182 	    } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
   183 	    
   184 	  } //for out edges wv 
   185 	
   186 	
   187 	if ( exc > 0 ) {	
   188 	  for( InEdgeIt e=G.template first<InEdgeIt>(w); e.valid(); ++e) {
   189 	    
   190 	    if( flow.get(e) == 0 ) continue; 
   191 	    NodeIt v=G.tail(e);  
   192 	    //e=vw
   193 	    
   194 	    if( lev > level.get(v) ) {  
   195 	      /*Push is allowed now*/
   196 	      
   197 	      if ( excess.get(v)==0 && v != s && v !=t) 
   198 		stack[level.get(v)].push(v); 
   199 	      /*v becomes active.*/
   200 	      
   201 	      int flo=flow.get(e);
   202 	      
   203 	      if ( flo >= exc ) { 
   204 		/*A nonsaturating push.*/
   205 		
   206 		flow.set(e, flo-exc);
   207 		excess.set(v, excess.get(v)+exc);
   208 		exc=0;
   209 		break; 
   210 	      } else {                                               
   211 		/*A saturating push.*/
   212 		
   213 		excess.set(v, excess.get(v)+flo);
   214 		exc-=flo;
   215 		flow.set(e,0);
   216 	      }  
   217 	    } else if ( newlevel > level.get(v) ) newlevel = level.get(v);
   218 	    
   219 	  } //for in edges vw
   220 	  
   221 	} // if w still has excess after the out edge for cycle
   222 	
   223 	excess.set(w, exc);
   224 	
   225 
   226 	
   227 
   228 	/*
   229 	  Relabel
   230 	*/
   231 	
   232 	if ( exc > 0 ) {
   233 	  //now 'lev' is the old level of w
   234 	  level.set(w,++newlevel);
   235 	  
   236 	  if ( lev < n ) {
   237 	    --numb[lev];
   238 	    
   239 	    if ( !numb[lev] && lev < A*n ) {  //If the level of w gets empty. 
   240 	      
   241 	      for (EachNodeIt v=G.template first<EachNodeIt>(); v.valid() ; ++v) {
   242 		if (level.get(v) > lev && level.get(v) < n ) level.set(v,n);  
   243 	      }
   244 	      for (int i=lev+1 ; i!=n ; ++i) numb[i]=0; 
   245 	      if ( newlevel < n ) newlevel=n; 
   246 	    } else { 
   247 	      if ( newlevel < n ) ++numb[newlevel]; 
   248 	    }
   249 	  } 
   250 	  
   251 	  stack[newlevel].push(w);
   252 	  b=newlevel;
   253 	  
   254 	}
   255 	
   256       } // while(b)
   257       
   258       
   259       value = excess.get(t);
   260       /*Max flow value.*/
   261 
   262 
   263     } //void run()
   264 
   265 
   266 
   267 
   268 
   269     /*
   270       Returns the maximum value of a flow.
   271      */
   272 
   273     T maxflow() {
   274       return value;
   275     }
   276 
   277 
   278 
   279     /*
   280       For the maximum flow x found by the algorithm, it returns the flow value on Edge e, i.e. x(e). 
   281     */
   282 
   283     T flowonedge(const EdgeIt e) {
   284       return flow.get(e);
   285     }
   286 
   287 
   288 
   289     /*
   290       Returns the maximum flow x found by the algorithm.
   291     */
   292 
   293     FlowMap allflow() {
   294       return flow;
   295     }
   296 
   297 
   298 
   299 
   300     /*
   301       Returns the minimum min cut, by a bfs from s in the residual graph.
   302     */
   303     
   304     template<typename CutMap>
   305     void mincut(CutMap& M) {
   306     
   307       std::queue<NodeIt> queue;
   308       
   309       M.set(s,true);      
   310       queue.push(s);
   311 
   312       while (!queue.empty()) {
   313         NodeIt w=queue.front();
   314 	queue.pop();
   315 	
   316 	for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
   317 	  NodeIt v=G.head(e);
   318 	  if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
   319 	    queue.push(v);
   320 	    M.set(v, true);
   321 	  }
   322 	} 
   323 
   324 	for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
   325 	  NodeIt v=G.tail(e);
   326 	  if (!M.get(v) && flow.get(e) > 0 ) {
   327 	    queue.push(v);
   328 	    M.set(v, true);
   329 	  }
   330 	}
   331 
   332       }
   333     }
   334 
   335 
   336 
   337     /*
   338       Returns the maximum min cut, by a reverse bfs 
   339       from t in the residual graph.
   340     */
   341     
   342     template<typename CutMap>
   343     void max_mincut(CutMap& M) {
   344     
   345       std::queue<NodeIt> queue;
   346       
   347       M.set(t,true);        
   348       queue.push(t);
   349 
   350       while (!queue.empty()) {
   351         NodeIt w=queue.front();
   352 	queue.pop();
   353 
   354 	for(InEdgeIt e=G.template first<InEdgeIt>(w) ; e.valid(); ++e) {
   355 	  NodeIt v=G.tail(e);
   356 	  if (!M.get(v) && flow.get(e) < capacity.get(e) ) {
   357 	    queue.push(v);
   358 	    M.set(v, true);
   359 	  }
   360 	}
   361 
   362 	for(OutEdgeIt e=G.template first<OutEdgeIt>(w) ; e.valid(); ++e) {
   363 	  NodeIt v=G.head(e);
   364 	  if (!M.get(v) && flow.get(e) > 0 ) {
   365 	    queue.push(v);
   366 	    M.set(v, true);
   367 	  }
   368 	}
   369       }
   370 
   371       for(EachNodeIt v=G.template first<EachNodeIt>() ; v.valid(); ++v) {
   372 	M.set(v, !M.get(v));
   373       }
   374 
   375     }
   376 
   377 
   378 
   379     template<typename CutMap>
   380     void min_mincut(CutMap& M) {
   381       mincut(M);
   382     }
   383 
   384 
   385 
   386   };
   387 }//namespace marci
   388 #endif 
   389 
   390 
   391 
   392