preflow.h

Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 * src/lemon/preflow.h - Part of LEMON, a generic C++ optimization library 00003 * 00004 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 00005 * (Egervary Combinatorial Optimization Research Group, EGRES). 00006 * 00007 * Permission to use, modify and distribute this software is granted 00008 * provided that this copyright notice appears in all copies. For 00009 * precise terms see the accompanying LICENSE file. 00010 * 00011 * This software is provided "AS IS" with no warranty of any kind, 00012 * express or implied, and with no claim as to its suitability for any 00013 * purpose. 00014 * 00015 */ 00016 00017 #ifndef LEMON_PREFLOW_H 00018 #define LEMON_PREFLOW_H 00019 00020 #include <vector> 00021 #include <queue> 00022 00023 #include <lemon/invalid.h> 00024 #include <lemon/maps.h> 00025 00029 00030 namespace lemon { 00031 00034 00036 00061 template <typename Graph, typename Num, 00062 typename CapMap=typename Graph::template EdgeMap<Num>, 00063 typename FlowMap=typename Graph::template EdgeMap<Num> > 00064 class Preflow { 00065 protected: 00066 typedef typename Graph::Node Node; 00067 typedef typename Graph::NodeIt NodeIt; 00068 typedef typename Graph::EdgeIt EdgeIt; 00069 typedef typename Graph::OutEdgeIt OutEdgeIt; 00070 typedef typename Graph::InEdgeIt InEdgeIt; 00071 00072 typedef typename Graph::template NodeMap<Node> NNMap; 00073 typedef typename std::vector<Node> VecNode; 00074 00075 const Graph* g; 00076 Node s; 00077 Node t; 00078 const CapMap* capacity; 00079 FlowMap* flow; 00080 int n; //the number of nodes of G 00081 00082 typename Graph::template NodeMap<int> level; 00083 typename Graph::template NodeMap<Num> excess; 00084 00085 // constants used for heuristics 00086 static const int H0=20; 00087 static const int H1=1; 00088 00089 public: 00090 00092 00104 enum FlowEnum{ 00105 NO_FLOW, 00106 ZERO_FLOW, 00107 GEN_FLOW, 00108 PRE_FLOW 00109 }; 00110 00112 00118 enum StatusEnum { 00119 AFTER_NOTHING, 00120 AFTER_PREFLOW_PHASE_1, 00121 AFTER_PREFLOW_PHASE_2 00122 }; 00123 00124 protected: 00125 FlowEnum flow_prop; 00126 StatusEnum status; // Do not needle this flag only if necessary. 00127 00128 public: 00130 00140 Preflow(const Graph& _G, Node _s, Node _t, 00141 const CapMap& _capacity, FlowMap& _flow) : 00142 g(&_G), s(_s), t(_t), capacity(&_capacity), 00143 flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0), 00144 flow_prop(NO_FLOW), status(AFTER_NOTHING) { } 00145 00146 00147 00149 00152 void run() { 00153 phase1(flow_prop); 00154 phase2(); 00155 } 00156 00158 00167 void run(FlowEnum fp) { 00168 flow_prop=fp; 00169 run(); 00170 } 00171 00173 00187 void phase1(FlowEnum fp) 00188 { 00189 flow_prop=fp; 00190 phase1(); 00191 } 00192 00193 00195 00204 void phase1() 00205 { 00206 int heur0=(int)(H0*n); //time while running 'bound decrease' 00207 int heur1=(int)(H1*n); //time while running 'highest label' 00208 int heur=heur1; //starting time interval (#of relabels) 00209 int numrelabel=0; 00210 00211 bool what_heur=1; 00212 //It is 0 in case 'bound decrease' and 1 in case 'highest label' 00213 00214 bool end=false; 00215 //Needed for 'bound decrease', true means no active 00216 //nodes are above bound b. 00217 00218 int k=n-2; //bound on the highest level under n containing a node 00219 int b=k; //bound on the highest level under n of an active node 00220 00221 VecNode first(n, INVALID); 00222 NNMap next(*g, INVALID); 00223 00224 NNMap left(*g, INVALID); 00225 NNMap right(*g, INVALID); 00226 VecNode level_list(n,INVALID); 00227 //List of the nodes in level i<n, set to n. 00228 00229 preflowPreproc(first, next, level_list, left, right); 00230 00231 //Push/relabel on the highest level active nodes. 00232 while ( true ) { 00233 if ( b == 0 ) { 00234 if ( !what_heur && !end && k > 0 ) { 00235 b=k; 00236 end=true; 00237 } else break; 00238 } 00239 00240 if ( first[b]==INVALID ) --b; 00241 else { 00242 end=false; 00243 Node w=first[b]; 00244 first[b]=next[w]; 00245 int newlevel=push(w, next, first); 00246 if ( excess[w] > 0 ) relabel(w, newlevel, first, next, level_list, 00247 left, right, b, k, what_heur); 00248 00249 ++numrelabel; 00250 if ( numrelabel >= heur ) { 00251 numrelabel=0; 00252 if ( what_heur ) { 00253 what_heur=0; 00254 heur=heur0; 00255 end=false; 00256 } else { 00257 what_heur=1; 00258 heur=heur1; 00259 b=k; 00260 } 00261 } 00262 } 00263 } 00264 flow_prop=PRE_FLOW; 00265 status=AFTER_PREFLOW_PHASE_1; 00266 } 00267 // Heuristics: 00268 // 2 phase 00269 // gap 00270 // list 'level_list' on the nodes on level i implemented by hand 00271 // stack 'active' on the active nodes on level i 00272 // runs heuristic 'highest label' for H1*n relabels 00273 // runs heuristic 'bound decrease' for H0*n relabels, starts with 'highest label' 00274 // Parameters H0 and H1 are initialized to 20 and 1. 00275 00276 00278 00286 void phase2() 00287 { 00288 00289 int k=n-2; //bound on the highest level under n containing a node 00290 int b=k; //bound on the highest level under n of an active node 00291 00292 00293 VecNode first(n, INVALID); 00294 NNMap next(*g, INVALID); 00295 level.set(s,0); 00296 std::queue<Node> bfs_queue; 00297 bfs_queue.push(s); 00298 00299 while ( !bfs_queue.empty() ) { 00300 00301 Node v=bfs_queue.front(); 00302 bfs_queue.pop(); 00303 int l=level[v]+1; 00304 00305 for(InEdgeIt e(*g,v); e!=INVALID; ++e) { 00306 if ( (*capacity)[e] <= (*flow)[e] ) continue; 00307 Node u=g->tail(e); 00308 if ( level[u] >= n ) { 00309 bfs_queue.push(u); 00310 level.set(u, l); 00311 if ( excess[u] > 0 ) { 00312 next.set(u,first[l]); 00313 first[l]=u; 00314 } 00315 } 00316 } 00317 00318 for(OutEdgeIt e(*g,v); e!=INVALID; ++e) { 00319 if ( 0 >= (*flow)[e] ) continue; 00320 Node u=g->head(e); 00321 if ( level[u] >= n ) { 00322 bfs_queue.push(u); 00323 level.set(u, l); 00324 if ( excess[u] > 0 ) { 00325 next.set(u,first[l]); 00326 first[l]=u; 00327 } 00328 } 00329 } 00330 } 00331 b=n-2; 00332 00333 while ( true ) { 00334 00335 if ( b == 0 ) break; 00336 if ( first[b]==INVALID ) --b; 00337 else { 00338 Node w=first[b]; 00339 first[b]=next[w]; 00340 int newlevel=push(w,next, first); 00341 00342 //relabel 00343 if ( excess[w] > 0 ) { 00344 level.set(w,++newlevel); 00345 next.set(w,first[newlevel]); 00346 first[newlevel]=w; 00347 b=newlevel; 00348 } 00349 } 00350 } // while(true) 00351 flow_prop=GEN_FLOW; 00352 status=AFTER_PREFLOW_PHASE_2; 00353 } 00354 00356 00360 Num flowValue() const { 00361 return excess[t]; 00362 } 00363 00364 00366 00373 template<typename _CutMap> 00374 void minCut(_CutMap& M) const { 00375 switch ( status ) { 00376 case AFTER_PREFLOW_PHASE_1: 00377 for(NodeIt v(*g); v!=INVALID; ++v) { 00378 if (level[v] < n) { 00379 M.set(v, false); 00380 } else { 00381 M.set(v, true); 00382 } 00383 } 00384 break; 00385 case AFTER_PREFLOW_PHASE_2: 00386 minMinCut(M); 00387 break; 00388 case AFTER_NOTHING: 00389 break; 00390 } 00391 } 00392 00394 00400 template<typename _CutMap> 00401 void minMinCut(_CutMap& M) const { 00402 00403 std::queue<Node> queue; 00404 M.set(s,true); 00405 queue.push(s); 00406 00407 while (!queue.empty()) { 00408 Node w=queue.front(); 00409 queue.pop(); 00410 00411 for(OutEdgeIt e(*g,w) ; e!=INVALID; ++e) { 00412 Node v=g->head(e); 00413 if (!M[v] && (*flow)[e] < (*capacity)[e] ) { 00414 queue.push(v); 00415 M.set(v, true); 00416 } 00417 } 00418 00419 for(InEdgeIt e(*g,w) ; e!=INVALID; ++e) { 00420 Node v=g->tail(e); 00421 if (!M[v] && (*flow)[e] > 0 ) { 00422 queue.push(v); 00423 M.set(v, true); 00424 } 00425 } 00426 } 00427 } 00428 00430 00435 template<typename _CutMap> 00436 void maxMinCut(_CutMap& M) const { 00437 00438 for(NodeIt v(*g) ; v!=INVALID; ++v) M.set(v, true); 00439 00440 std::queue<Node> queue; 00441 00442 M.set(t,false); 00443 queue.push(t); 00444 00445 while (!queue.empty()) { 00446 Node w=queue.front(); 00447 queue.pop(); 00448 00449 for(InEdgeIt e(*g,w) ; e!=INVALID; ++e) { 00450 Node v=g->tail(e); 00451 if (M[v] && (*flow)[e] < (*capacity)[e] ) { 00452 queue.push(v); 00453 M.set(v, false); 00454 } 00455 } 00456 00457 for(OutEdgeIt e(*g,w) ; e!=INVALID; ++e) { 00458 Node v=g->head(e); 00459 if (M[v] && (*flow)[e] > 0 ) { 00460 queue.push(v); 00461 M.set(v, false); 00462 } 00463 } 00464 } 00465 } 00466 00468 00471 void setSource(Node _s) { 00472 s=_s; 00473 if ( flow_prop != ZERO_FLOW ) flow_prop=NO_FLOW; 00474 status=AFTER_NOTHING; 00475 } 00476 00478 00481 void setTarget(Node _t) { 00482 t=_t; 00483 if ( flow_prop == GEN_FLOW ) flow_prop=PRE_FLOW; 00484 status=AFTER_NOTHING; 00485 } 00486 00488 00491 void setCap(const CapMap& _cap) { 00492 capacity=&_cap; 00493 status=AFTER_NOTHING; 00494 } 00495 00497 00500 void setFlow(FlowMap& _flow) { 00501 flow=&_flow; 00502 flow_prop=NO_FLOW; 00503 status=AFTER_NOTHING; 00504 } 00505 00506 00507 private: 00508 00509 int push(Node w, NNMap& next, VecNode& first) { 00510 00511 int lev=level[w]; 00512 Num exc=excess[w]; 00513 int newlevel=n; //bound on the next level of w 00514 00515 for(OutEdgeIt e(*g,w) ; e!=INVALID; ++e) { 00516 if ( (*flow)[e] >= (*capacity)[e] ) continue; 00517 Node v=g->head(e); 00518 00519 if( lev > level[v] ) { //Push is allowed now 00520 00521 if ( excess[v]<=0 && v!=t && v!=s ) { 00522 next.set(v,first[level[v]]); 00523 first[level[v]]=v; 00524 } 00525 00526 Num cap=(*capacity)[e]; 00527 Num flo=(*flow)[e]; 00528 Num remcap=cap-flo; 00529 00530 if ( remcap >= exc ) { //A nonsaturating push. 00531 00532 flow->set(e, flo+exc); 00533 excess.set(v, excess[v]+exc); 00534 exc=0; 00535 break; 00536 00537 } else { //A saturating push. 00538 flow->set(e, cap); 00539 excess.set(v, excess[v]+remcap); 00540 exc-=remcap; 00541 } 00542 } else if ( newlevel > level[v] ) newlevel = level[v]; 00543 } //for out edges wv 00544 00545 if ( exc > 0 ) { 00546 for(InEdgeIt e(*g,w) ; e!=INVALID; ++e) { 00547 00548 if( (*flow)[e] <= 0 ) continue; 00549 Node v=g->tail(e); 00550 00551 if( lev > level[v] ) { //Push is allowed now 00552 00553 if ( excess[v]<=0 && v!=t && v!=s ) { 00554 next.set(v,first[level[v]]); 00555 first[level[v]]=v; 00556 } 00557 00558 Num flo=(*flow)[e]; 00559 00560 if ( flo >= exc ) { //A nonsaturating push. 00561 00562 flow->set(e, flo-exc); 00563 excess.set(v, excess[v]+exc); 00564 exc=0; 00565 break; 00566 } else { //A saturating push. 00567 00568 excess.set(v, excess[v]+flo); 00569 exc-=flo; 00570 flow->set(e,0); 00571 } 00572 } else if ( newlevel > level[v] ) newlevel = level[v]; 00573 } //for in edges vw 00574 00575 } // if w still has excess after the out edge for cycle 00576 00577 excess.set(w, exc); 00578 00579 return newlevel; 00580 } 00581 00582 00583 00584 void preflowPreproc(VecNode& first, NNMap& next, 00585 VecNode& level_list, NNMap& left, NNMap& right) 00586 { 00587 for(NodeIt v(*g); v!=INVALID; ++v) level.set(v,n); 00588 std::queue<Node> bfs_queue; 00589 00590 if ( flow_prop == GEN_FLOW || flow_prop == PRE_FLOW ) { 00591 //Reverse_bfs from t in the residual graph, 00592 //to find the starting level. 00593 level.set(t,0); 00594 bfs_queue.push(t); 00595 00596 while ( !bfs_queue.empty() ) { 00597 00598 Node v=bfs_queue.front(); 00599 bfs_queue.pop(); 00600 int l=level[v]+1; 00601 00602 for(InEdgeIt e(*g,v) ; e!=INVALID; ++e) { 00603 if ( (*capacity)[e] <= (*flow)[e] ) continue; 00604 Node w=g->tail(e); 00605 if ( level[w] == n && w != s ) { 00606 bfs_queue.push(w); 00607 Node z=level_list[l]; 00608 if ( z!=INVALID ) left.set(z,w); 00609 right.set(w,z); 00610 level_list[l]=w; 00611 level.set(w, l); 00612 } 00613 } 00614 00615 for(OutEdgeIt e(*g,v) ; e!=INVALID; ++e) { 00616 if ( 0 >= (*flow)[e] ) continue; 00617 Node w=g->head(e); 00618 if ( level[w] == n && w != s ) { 00619 bfs_queue.push(w); 00620 Node z=level_list[l]; 00621 if ( z!=INVALID ) left.set(z,w); 00622 right.set(w,z); 00623 level_list[l]=w; 00624 level.set(w, l); 00625 } 00626 } 00627 } //while 00628 } //if 00629 00630 00631 switch (flow_prop) { 00632 case NO_FLOW: 00633 for(EdgeIt e(*g); e!=INVALID; ++e) flow->set(e,0); 00634 case ZERO_FLOW: 00635 for(NodeIt v(*g); v!=INVALID; ++v) excess.set(v,0); 00636 00637 //Reverse_bfs from t, to find the starting level. 00638 level.set(t,0); 00639 bfs_queue.push(t); 00640 00641 while ( !bfs_queue.empty() ) { 00642 00643 Node v=bfs_queue.front(); 00644 bfs_queue.pop(); 00645 int l=level[v]+1; 00646 00647 for(InEdgeIt e(*g,v) ; e!=INVALID; ++e) { 00648 Node w=g->tail(e); 00649 if ( level[w] == n && w != s ) { 00650 bfs_queue.push(w); 00651 Node z=level_list[l]; 00652 if ( z!=INVALID ) left.set(z,w); 00653 right.set(w,z); 00654 level_list[l]=w; 00655 level.set(w, l); 00656 } 00657 } 00658 } 00659 00660 //the starting flow 00661 for(OutEdgeIt e(*g,s) ; e!=INVALID; ++e) { 00662 Num c=(*capacity)[e]; 00663 if ( c <= 0 ) continue; 00664 Node w=g->head(e); 00665 if ( level[w] < n ) { 00666 if ( excess[w] <= 0 && w!=t ) { //putting into the stack 00667 next.set(w,first[level[w]]); 00668 first[level[w]]=w; 00669 } 00670 flow->set(e, c); 00671 excess.set(w, excess[w]+c); 00672 } 00673 } 00674 break; 00675 00676 case GEN_FLOW: 00677 for(NodeIt v(*g); v!=INVALID; ++v) excess.set(v,0); 00678 { 00679 Num exc=0; 00680 for(InEdgeIt e(*g,t) ; e!=INVALID; ++e) exc+=(*flow)[e]; 00681 for(OutEdgeIt e(*g,t) ; e!=INVALID; ++e) exc-=(*flow)[e]; 00682 excess.set(t,exc); 00683 } 00684 00685 //the starting flow 00686 for(OutEdgeIt e(*g,s); e!=INVALID; ++e) { 00687 Num rem=(*capacity)[e]-(*flow)[e]; 00688 if ( rem <= 0 ) continue; 00689 Node w=g->head(e); 00690 if ( level[w] < n ) { 00691 if ( excess[w] <= 0 && w!=t ) { //putting into the stack 00692 next.set(w,first[level[w]]); 00693 first[level[w]]=w; 00694 } 00695 flow->set(e, (*capacity)[e]); 00696 excess.set(w, excess[w]+rem); 00697 } 00698 } 00699 00700 for(InEdgeIt e(*g,s); e!=INVALID; ++e) { 00701 if ( (*flow)[e] <= 0 ) continue; 00702 Node w=g->tail(e); 00703 if ( level[w] < n ) { 00704 if ( excess[w] <= 0 && w!=t ) { 00705 next.set(w,first[level[w]]); 00706 first[level[w]]=w; 00707 } 00708 excess.set(w, excess[w]+(*flow)[e]); 00709 flow->set(e, 0); 00710 } 00711 } 00712 break; 00713 00714 case PRE_FLOW: 00715 //the starting flow 00716 for(OutEdgeIt e(*g,s) ; e!=INVALID; ++e) { 00717 Num rem=(*capacity)[e]-(*flow)[e]; 00718 if ( rem <= 0 ) continue; 00719 Node w=g->head(e); 00720 if ( level[w] < n ) flow->set(e, (*capacity)[e]); 00721 } 00722 00723 for(InEdgeIt e(*g,s) ; e!=INVALID; ++e) { 00724 if ( (*flow)[e] <= 0 ) continue; 00725 Node w=g->tail(e); 00726 if ( level[w] < n ) flow->set(e, 0); 00727 } 00728 00729 //computing the excess 00730 for(NodeIt w(*g); w!=INVALID; ++w) { 00731 Num exc=0; 00732 for(InEdgeIt e(*g,w); e!=INVALID; ++e) exc+=(*flow)[e]; 00733 for(OutEdgeIt e(*g,w); e!=INVALID; ++e) exc-=(*flow)[e]; 00734 excess.set(w,exc); 00735 00736 //putting the active nodes into the stack 00737 int lev=level[w]; 00738 if ( exc > 0 && lev < n && Node(w) != t ) { 00739 next.set(w,first[lev]); 00740 first[lev]=w; 00741 } 00742 } 00743 break; 00744 } //switch 00745 } //preflowPreproc 00746 00747 00748 void relabel(Node w, int newlevel, VecNode& first, NNMap& next, 00749 VecNode& level_list, NNMap& left, 00750 NNMap& right, int& b, int& k, bool what_heur ) 00751 { 00752 00753 int lev=level[w]; 00754 00755 Node right_n=right[w]; 00756 Node left_n=left[w]; 00757 00758 //unlacing starts 00759 if ( right_n!=INVALID ) { 00760 if ( left_n!=INVALID ) { 00761 right.set(left_n, right_n); 00762 left.set(right_n, left_n); 00763 } else { 00764 level_list[lev]=right_n; 00765 left.set(right_n, INVALID); 00766 } 00767 } else { 00768 if ( left_n!=INVALID ) { 00769 right.set(left_n, INVALID); 00770 } else { 00771 level_list[lev]=INVALID; 00772 } 00773 } 00774 //unlacing ends 00775 00776 if ( level_list[lev]==INVALID ) { 00777 00778 //gapping starts 00779 for (int i=lev; i!=k ; ) { 00780 Node v=level_list[++i]; 00781 while ( v!=INVALID ) { 00782 level.set(v,n); 00783 v=right[v]; 00784 } 00785 level_list[i]=INVALID; 00786 if ( !what_heur ) first[i]=INVALID; 00787 } 00788 00789 level.set(w,n); 00790 b=lev-1; 00791 k=b; 00792 //gapping ends 00793 00794 } else { 00795 00796 if ( newlevel == n ) level.set(w,n); 00797 else { 00798 level.set(w,++newlevel); 00799 next.set(w,first[newlevel]); 00800 first[newlevel]=w; 00801 if ( what_heur ) b=newlevel; 00802 if ( k < newlevel ) ++k; //now k=newlevel 00803 Node z=level_list[newlevel]; 00804 if ( z!=INVALID ) left.set(z,w); 00805 right.set(w,z); 00806 left.set(w,INVALID); 00807 level_list[newlevel]=w; 00808 } 00809 } 00810 } //relabel 00811 00812 }; 00813 } //namespace lemon 00814 00815 #endif //LEMON_PREFLOW_H 00816 00817 00818 00819

Generated on Thu Sep 30 12:18:33 2004 for LEMON by doxygen 1.3.8