Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

preflow.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  * lemon/preflow.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Research Group on Combinatorial Optimization, 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 #include <lemon/graph_utils.h>
00026 
00030 
00031 namespace lemon {
00032 
00035 
00037 
00063   template <typename Graph, typename Num,
00064             typename CapacityMap=typename Graph::template EdgeMap<Num>,
00065             typename FlowMap=typename Graph::template EdgeMap<Num> >
00066   class Preflow {
00067   protected:
00068     typedef typename Graph::Node Node;
00069     typedef typename Graph::NodeIt NodeIt;
00070     typedef typename Graph::EdgeIt EdgeIt;
00071     typedef typename Graph::OutEdgeIt OutEdgeIt;
00072     typedef typename Graph::InEdgeIt InEdgeIt;
00073 
00074     typedef typename Graph::template NodeMap<Node> NNMap;
00075     typedef typename std::vector<Node> VecNode;
00076 
00077     const Graph* _g;
00078     Node _source;
00079     Node _target;
00080     const CapacityMap* _capacity;
00081     FlowMap* _flow;
00082     int _node_num;      //the number of nodes of G
00083     
00084     typename Graph::template NodeMap<int> level;  
00085     typename Graph::template NodeMap<Num> excess;
00086 
00087     // constants used for heuristics
00088     static const int H0=20;
00089     static const int H1=1;
00090 
00091     public:
00092 
00094 
00107     enum FlowEnum{
00108       NO_FLOW,
00109       ZERO_FLOW,
00110       GEN_FLOW,
00111       PRE_FLOW
00112     };
00113 
00115 
00123     enum StatusEnum {
00124       AFTER_NOTHING,
00125       AFTER_PREFLOW_PHASE_1,      
00126       AFTER_PREFLOW_PHASE_2
00127     };
00128     
00129     protected: 
00130       FlowEnum flow_prop;
00131     StatusEnum status; // Do not needle this flag only if necessary.
00132     
00133   public: 
00135 
00145       Preflow(const Graph& _gr, Node _s, Node _t, 
00146               const CapacityMap& _cap, FlowMap& _f) :
00147         _g(&_gr), _source(_s), _target(_t), _capacity(&_cap),
00148         _flow(&_f), _node_num(countNodes(_gr)), level(_gr), excess(_gr,0), 
00149         flow_prop(NO_FLOW), status(AFTER_NOTHING) { }
00150 
00151 
00152                                                                               
00154 
00157     void run() {
00158       phase1(flow_prop);
00159       phase2();
00160     }
00161     
00163     
00172     void run(FlowEnum fp) {
00173       flow_prop=fp;
00174       run();
00175     }
00176       
00178 
00192     void phase1(FlowEnum fp)
00193     {
00194       flow_prop=fp;
00195       phase1();
00196     }
00197 
00198     
00200 
00209     void phase1()
00210     {
00211       int heur0=(int)(H0*_node_num);  //time while running 'bound decrease'
00212       int heur1=(int)(H1*_node_num);  //time while running 'highest label'
00213       int heur=heur1;         //starting time interval (#of relabels)
00214       int numrelabel=0;
00215 
00216       bool what_heur=1;
00217       //It is 0 in case 'bound decrease' and 1 in case 'highest label'
00218 
00219       bool end=false;
00220       //Needed for 'bound decrease', true means no active 
00221       //nodes are above bound b.
00222 
00223       int k=_node_num-2;  //bound on the highest level under n containing a node
00224       int b=k;    //bound on the highest level under n of an active node
00225 
00226       VecNode first(_node_num, INVALID);
00227       NNMap next(*_g, INVALID);
00228 
00229       NNMap left(*_g, INVALID);
00230       NNMap right(*_g, INVALID);
00231       VecNode level_list(_node_num,INVALID);
00232       //List of the nodes in level i<n, set to n.
00233 
00234       preflowPreproc(first, next, level_list, left, right);
00235 
00236       //Push/relabel on the highest level active nodes.
00237       while ( true ) {
00238         if ( b == 0 ) {
00239           if ( !what_heur && !end && k > 0 ) {
00240             b=k;
00241             end=true;
00242           } else break;
00243         }
00244 
00245         if ( first[b]==INVALID ) --b;
00246         else {
00247           end=false;
00248           Node w=first[b];
00249           first[b]=next[w];
00250           int newlevel=push(w, next, first);
00251           if ( excess[w] > 0 ) relabel(w, newlevel, first, next, level_list, 
00252                                        left, right, b, k, what_heur);
00253 
00254           ++numrelabel;
00255           if ( numrelabel >= heur ) {
00256             numrelabel=0;
00257             if ( what_heur ) {
00258               what_heur=0;
00259               heur=heur0;
00260               end=false;
00261             } else {
00262               what_heur=1;
00263               heur=heur1;
00264               b=k;
00265             }
00266           }
00267         }
00268       }
00269       flow_prop=PRE_FLOW;
00270       status=AFTER_PREFLOW_PHASE_1;
00271     }
00272     // Heuristics:
00273     //   2 phase
00274     //   gap
00275     //   list 'level_list' on the nodes on level i implemented by hand
00276     //   stack 'active' on the active nodes on level i      
00277     //   runs heuristic 'highest label' for H1*n relabels
00278     //   runs heuristic 'bound decrease' for H0*n relabels,
00279     //        starts with 'highest label'
00280     //   Parameters H0 and H1 are initialized to 20 and 1.
00281 
00282 
00284 
00293     void phase2()
00294     {
00295 
00296       int k=_node_num-2;  //bound on the highest level under n containing a node
00297       int b=k;    //bound on the highest level under n of an active node
00298 
00299     
00300       VecNode first(_node_num, INVALID);
00301       NNMap next(*_g, INVALID); 
00302       level.set(_source,0);
00303       std::queue<Node> bfs_queue;
00304       bfs_queue.push(_source);
00305 
00306       while ( !bfs_queue.empty() ) {
00307 
00308         Node v=bfs_queue.front();
00309         bfs_queue.pop();
00310         int l=level[v]+1;
00311 
00312         for(InEdgeIt e(*_g,v); e!=INVALID; ++e) {
00313           if ( (*_capacity)[e] <= (*_flow)[e] ) continue;
00314           Node u=_g->source(e);
00315           if ( level[u] >= _node_num ) {
00316             bfs_queue.push(u);
00317             level.set(u, l);
00318             if ( excess[u] > 0 ) {
00319               next.set(u,first[l]);
00320               first[l]=u;
00321             }
00322           }
00323         }
00324 
00325         for(OutEdgeIt e(*_g,v); e!=INVALID; ++e) {
00326           if ( 0 >= (*_flow)[e] ) continue;
00327           Node u=_g->target(e);
00328           if ( level[u] >= _node_num ) {
00329             bfs_queue.push(u);
00330             level.set(u, l);
00331             if ( excess[u] > 0 ) {
00332               next.set(u,first[l]);
00333               first[l]=u;
00334             }
00335           }
00336         }
00337       }
00338       b=_node_num-2;
00339 
00340       while ( true ) {
00341 
00342         if ( b == 0 ) break;
00343         if ( first[b]==INVALID ) --b;
00344         else {
00345           Node w=first[b];
00346           first[b]=next[w];
00347           int newlevel=push(w,next, first);
00348           
00349           //relabel
00350           if ( excess[w] > 0 ) {
00351             level.set(w,++newlevel);
00352             next.set(w,first[newlevel]);
00353             first[newlevel]=w;
00354             b=newlevel;
00355           }
00356         } 
00357       } // while(true)
00358       flow_prop=GEN_FLOW;
00359       status=AFTER_PREFLOW_PHASE_2;
00360     }
00361 
00363 
00367     Num flowValue() const {
00368       return excess[_target];
00369     }
00370 
00371 
00373 
00380     template<typename _CutMap>
00381     void minCut(_CutMap& M) const {
00382       switch ( status ) {
00383         case AFTER_PREFLOW_PHASE_1:
00384         for(NodeIt v(*_g); v!=INVALID; ++v) {
00385           if (level[v] < _node_num) {
00386             M.set(v, false);
00387           } else {
00388             M.set(v, true);
00389           }
00390         }
00391         break;
00392         case AFTER_PREFLOW_PHASE_2:
00393         minMinCut(M);
00394         break;
00395         case AFTER_NOTHING:
00396         break;
00397       }
00398     }
00399 
00401 
00407     template<typename _CutMap>
00408     void minMinCut(_CutMap& M) const {
00409 
00410       std::queue<Node> queue;
00411       M.set(_source,true);
00412       queue.push(_source);
00413       
00414       while (!queue.empty()) {
00415         Node w=queue.front();
00416         queue.pop();
00417         
00418         for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
00419           Node v=_g->target(e);
00420           if (!M[v] && (*_flow)[e] < (*_capacity)[e] ) {
00421             queue.push(v);
00422             M.set(v, true);
00423           }
00424         }
00425         
00426         for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
00427           Node v=_g->source(e);
00428           if (!M[v] && (*_flow)[e] > 0 ) {
00429             queue.push(v);
00430             M.set(v, true);
00431           }
00432         }
00433       }
00434     }
00435     
00437 
00442     template<typename _CutMap>
00443     void maxMinCut(_CutMap& M) const {
00444 
00445       for(NodeIt v(*_g) ; v!=INVALID; ++v) M.set(v, true);
00446 
00447       std::queue<Node> queue;
00448 
00449       M.set(_target,false);
00450       queue.push(_target);
00451 
00452       while (!queue.empty()) {
00453         Node w=queue.front();
00454         queue.pop();
00455 
00456         for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
00457           Node v=_g->source(e);
00458           if (M[v] && (*_flow)[e] < (*_capacity)[e] ) {
00459             queue.push(v);
00460             M.set(v, false);
00461           }
00462         }
00463 
00464         for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
00465           Node v=_g->target(e);
00466           if (M[v] && (*_flow)[e] > 0 ) {
00467             queue.push(v);
00468             M.set(v, false);
00469           }
00470         }
00471       }
00472     }
00473 
00475 
00478     void source(Node _s) { 
00479       _source=_s; 
00480       if ( flow_prop != ZERO_FLOW ) flow_prop=NO_FLOW;
00481       status=AFTER_NOTHING; 
00482     }
00483 
00485 
00488     Node source() const { 
00489       return _source;
00490     }
00491 
00493 
00496     void target(Node _t) { 
00497       _target=_t; 
00498       if ( flow_prop == GEN_FLOW ) flow_prop=PRE_FLOW;
00499       status=AFTER_NOTHING; 
00500     }
00501 
00503 
00506     Node target() const { 
00507       return _target;
00508     }
00509 
00511 
00514     void capacityMap(const CapacityMap& _cap) { 
00515       _capacity=&_cap; 
00516       status=AFTER_NOTHING; 
00517     }
00519 
00522     const CapacityMap &capacityMap() const { 
00523       return *_capacity;
00524     }
00525 
00527 
00530     void flowMap(FlowMap& _f) { 
00531       _flow=&_f; 
00532       flow_prop=NO_FLOW;
00533       status=AFTER_NOTHING; 
00534     }
00535      
00537 
00540     const FlowMap &flowMap() const { 
00541       return *_flow;
00542     }
00543 
00544   private:
00545 
00546     int push(Node w, NNMap& next, VecNode& first) {
00547 
00548       int lev=level[w];
00549       Num exc=excess[w];
00550       int newlevel=_node_num;       //bound on the next level of w
00551 
00552       for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
00553         if ( (*_flow)[e] >= (*_capacity)[e] ) continue;
00554         Node v=_g->target(e);
00555 
00556         if( lev > level[v] ) { //Push is allowed now
00557           
00558           if ( excess[v]<=0 && v!=_target && v!=_source ) {
00559             next.set(v,first[level[v]]);
00560             first[level[v]]=v;
00561           }
00562 
00563           Num cap=(*_capacity)[e];
00564           Num flo=(*_flow)[e];
00565           Num remcap=cap-flo;
00566           
00567           if ( remcap >= exc ) { //A nonsaturating push.
00568             
00569             _flow->set(e, flo+exc);
00570             excess.set(v, excess[v]+exc);
00571             exc=0;
00572             break;
00573 
00574           } else { //A saturating push.
00575             _flow->set(e, cap);
00576             excess.set(v, excess[v]+remcap);
00577             exc-=remcap;
00578           }
00579         } else if ( newlevel > level[v] ) newlevel = level[v];
00580       } //for out edges wv
00581 
00582       if ( exc > 0 ) {
00583         for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
00584           
00585           if( (*_flow)[e] <= 0 ) continue;
00586           Node v=_g->source(e);
00587 
00588           if( lev > level[v] ) { //Push is allowed now
00589 
00590             if ( excess[v]<=0 && v!=_target && v!=_source ) {
00591               next.set(v,first[level[v]]);
00592               first[level[v]]=v;
00593             }
00594 
00595             Num flo=(*_flow)[e];
00596 
00597             if ( flo >= exc ) { //A nonsaturating push.
00598 
00599               _flow->set(e, flo-exc);
00600               excess.set(v, excess[v]+exc);
00601               exc=0;
00602               break;
00603             } else {  //A saturating push.
00604 
00605               excess.set(v, excess[v]+flo);
00606               exc-=flo;
00607               _flow->set(e,0);
00608             }
00609           } else if ( newlevel > level[v] ) newlevel = level[v];
00610         } //for in edges vw
00611 
00612       } // if w still has excess after the out edge for cycle
00613 
00614       excess.set(w, exc);
00615       
00616       return newlevel;
00617     }
00618     
00619     
00620     
00621     void preflowPreproc(VecNode& first, NNMap& next, 
00622                         VecNode& level_list, NNMap& left, NNMap& right)
00623     {
00624       for(NodeIt v(*_g); v!=INVALID; ++v) level.set(v,_node_num);
00625       std::queue<Node> bfs_queue;
00626       
00627       if ( flow_prop == GEN_FLOW || flow_prop == PRE_FLOW ) {
00628         //Reverse_bfs from t in the residual graph,
00629         //to find the starting level.
00630         level.set(_target,0);
00631         bfs_queue.push(_target);
00632         
00633         while ( !bfs_queue.empty() ) {
00634           
00635           Node v=bfs_queue.front();
00636           bfs_queue.pop();
00637           int l=level[v]+1;
00638           
00639           for(InEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
00640             if ( (*_capacity)[e] <= (*_flow)[e] ) continue;
00641             Node w=_g->source(e);
00642             if ( level[w] == _node_num && w != _source ) {
00643               bfs_queue.push(w);
00644               Node z=level_list[l];
00645               if ( z!=INVALID ) left.set(z,w);
00646               right.set(w,z);
00647               level_list[l]=w;
00648               level.set(w, l);
00649             }
00650           }
00651           
00652           for(OutEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
00653             if ( 0 >= (*_flow)[e] ) continue;
00654             Node w=_g->target(e);
00655             if ( level[w] == _node_num && w != _source ) {
00656               bfs_queue.push(w);
00657               Node z=level_list[l];
00658               if ( z!=INVALID ) left.set(z,w);
00659               right.set(w,z);
00660               level_list[l]=w;
00661               level.set(w, l);
00662             }
00663           }
00664         } //while
00665       } //if
00666 
00667 
00668       switch (flow_prop) {
00669         case NO_FLOW:  
00670         for(EdgeIt e(*_g); e!=INVALID; ++e) _flow->set(e,0);
00671         case ZERO_FLOW:
00672         for(NodeIt v(*_g); v!=INVALID; ++v) excess.set(v,0);
00673         
00674         //Reverse_bfs from t, to find the starting level.
00675         level.set(_target,0);
00676         bfs_queue.push(_target);
00677         
00678         while ( !bfs_queue.empty() ) {
00679           
00680           Node v=bfs_queue.front();
00681           bfs_queue.pop();
00682           int l=level[v]+1;
00683           
00684           for(InEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
00685             Node w=_g->source(e);
00686             if ( level[w] == _node_num && w != _source ) {
00687               bfs_queue.push(w);
00688               Node z=level_list[l];
00689               if ( z!=INVALID ) left.set(z,w);
00690               right.set(w,z);
00691               level_list[l]=w;
00692               level.set(w, l);
00693             }
00694           }
00695         }
00696         
00697         //the starting flow
00698         for(OutEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
00699           Num c=(*_capacity)[e];
00700           if ( c <= 0 ) continue;
00701           Node w=_g->target(e);
00702           if ( level[w] < _node_num ) {
00703             if ( excess[w] <= 0 && w!=_target ) { //putting into the stack
00704               next.set(w,first[level[w]]);
00705               first[level[w]]=w;
00706             }
00707             _flow->set(e, c);
00708             excess.set(w, excess[w]+c);
00709           }
00710         }
00711         break;
00712 
00713         case GEN_FLOW:
00714         for(NodeIt v(*_g); v!=INVALID; ++v) excess.set(v,0);
00715         {
00716           Num exc=0;
00717           for(InEdgeIt e(*_g,_target) ; e!=INVALID; ++e) exc+=(*_flow)[e];
00718           for(OutEdgeIt e(*_g,_target) ; e!=INVALID; ++e) exc-=(*_flow)[e];
00719           excess.set(_target,exc);
00720         }
00721 
00722         //the starting flow
00723         for(OutEdgeIt e(*_g,_source); e!=INVALID; ++e)  {
00724           Num rem=(*_capacity)[e]-(*_flow)[e];
00725           if ( rem <= 0 ) continue;
00726           Node w=_g->target(e);
00727           if ( level[w] < _node_num ) {
00728             if ( excess[w] <= 0 && w!=_target ) { //putting into the stack
00729               next.set(w,first[level[w]]);
00730               first[level[w]]=w;
00731             }   
00732             _flow->set(e, (*_capacity)[e]);
00733             excess.set(w, excess[w]+rem);
00734           }
00735         }
00736         
00737         for(InEdgeIt e(*_g,_source); e!=INVALID; ++e) {
00738           if ( (*_flow)[e] <= 0 ) continue;
00739           Node w=_g->source(e);
00740           if ( level[w] < _node_num ) {
00741             if ( excess[w] <= 0 && w!=_target ) {
00742               next.set(w,first[level[w]]);
00743               first[level[w]]=w;
00744             }  
00745             excess.set(w, excess[w]+(*_flow)[e]);
00746             _flow->set(e, 0);
00747           }
00748         }
00749         break;
00750 
00751         case PRE_FLOW:  
00752         //the starting flow
00753         for(OutEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
00754           Num rem=(*_capacity)[e]-(*_flow)[e];
00755           if ( rem <= 0 ) continue;
00756           Node w=_g->target(e);
00757           if ( level[w] < _node_num ) _flow->set(e, (*_capacity)[e]);
00758         }
00759         
00760         for(InEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
00761           if ( (*_flow)[e] <= 0 ) continue;
00762           Node w=_g->source(e);
00763           if ( level[w] < _node_num ) _flow->set(e, 0);
00764         }
00765         
00766         //computing the excess
00767         for(NodeIt w(*_g); w!=INVALID; ++w) {
00768           Num exc=0;
00769           for(InEdgeIt e(*_g,w); e!=INVALID; ++e) exc+=(*_flow)[e];
00770           for(OutEdgeIt e(*_g,w); e!=INVALID; ++e) exc-=(*_flow)[e];
00771           excess.set(w,exc);
00772           
00773           //putting the active nodes into the stack
00774           int lev=level[w];
00775             if ( exc > 0 && lev < _node_num && Node(w) != _target ) {
00776               next.set(w,first[lev]);
00777               first[lev]=w;
00778             }
00779         }
00780         break;
00781       } //switch
00782     } //preflowPreproc
00783 
00784 
00785     void relabel(Node w, int newlevel, VecNode& first, NNMap& next, 
00786                  VecNode& level_list, NNMap& left,
00787                  NNMap& right, int& b, int& k, bool what_heur )
00788     {
00789 
00790       int lev=level[w];
00791 
00792       Node right_n=right[w];
00793       Node left_n=left[w];
00794 
00795       //unlacing starts
00796       if ( right_n!=INVALID ) {
00797         if ( left_n!=INVALID ) {
00798           right.set(left_n, right_n);
00799           left.set(right_n, left_n);
00800         } else {
00801           level_list[lev]=right_n;
00802           left.set(right_n, INVALID);
00803         }
00804       } else {
00805         if ( left_n!=INVALID ) {
00806           right.set(left_n, INVALID);
00807         } else {
00808           level_list[lev]=INVALID;
00809         }
00810       }
00811       //unlacing ends
00812 
00813       if ( level_list[lev]==INVALID ) {
00814 
00815         //gapping starts
00816         for (int i=lev; i!=k ; ) {
00817           Node v=level_list[++i];
00818           while ( v!=INVALID ) {
00819             level.set(v,_node_num);
00820             v=right[v];
00821           }
00822           level_list[i]=INVALID;
00823           if ( !what_heur ) first[i]=INVALID;
00824         }
00825 
00826         level.set(w,_node_num);
00827         b=lev-1;
00828         k=b;
00829         //gapping ends
00830 
00831       } else {
00832 
00833         if ( newlevel == _node_num ) level.set(w,_node_num);
00834         else {
00835           level.set(w,++newlevel);
00836           next.set(w,first[newlevel]);
00837           first[newlevel]=w;
00838           if ( what_heur ) b=newlevel;
00839           if ( k < newlevel ) ++k;      //now k=newlevel
00840           Node z=level_list[newlevel];
00841           if ( z!=INVALID ) left.set(z,w);
00842           right.set(w,z);
00843           left.set(w,INVALID);
00844           level_list[newlevel]=w;
00845         }
00846       }
00847     } //relabel
00848 
00849   }; 
00850 
00852 
00856   template<class GR, class CM, class FM>
00857   Preflow<GR,typename CM::Value,CM,FM> preflow(const GR &g,
00858                             typename GR::Node source,
00859                             typename GR::Node target,
00860                             const CM &cap,
00861                             FM &flow
00862                             )
00863   {
00864     return Preflow<GR,typename CM::Value,CM,FM>(g,source,target,cap,flow);
00865   }
00866 
00867 } //namespace lemon
00868 
00869 #endif //LEMON_PREFLOW_H

Generated on Sat Aug 27 14:14:54 2005 for LEMON by  doxygen 1.4.4