COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/jacint/max_flow.h @ 626:0015642b0990

Last change on this file since 626:0015642b0990 was 615:b6b31b75b522, checked in by marci, 20 years ago

docs, max_flow improvments

File size: 26.6 KB
RevLine 
[478]1// -*- C++ -*-
2
3/*
[615]4  Heuristics:
[485]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'
[615]11
[485]12  Parameters H0 and H1 are initialized to 20 and 1.
[478]13
[485]14  Constructors:
[478]15
[615]16  Preflow(Graph, Node, Node, CapMap, FlowMap, bool) : bool must be false if
[485]17  FlowMap is not constant zero, and should be true if it is
[478]18
[485]19  Members:
[478]20
[485]21  void run()
[478]22
[485]23  Num flowValue() : returns the value of a maximum flow
[478]24
[615]25  void minMinCut(CutMap& M) : sets M to the characteristic vector of the
[485]26  minimum min cut. M should be a map of bools initialized to false. ??Is it OK?
[478]27
[615]28  void maxMinCut(CutMap& M) : sets M to the characteristic vector of the
[485]29  maximum min cut. M should be a map of bools initialized to false.
[478]30
[615]31  void minCut(CutMap& M) : sets M to the characteristic vector of
[485]32  a min cut. M should be a map of bools initialized to false.
[478]33
34*/
35
[480]36#ifndef HUGO_MAX_FLOW_H
37#define HUGO_MAX_FLOW_H
[478]38
39#include <vector>
40#include <queue>
41#include <stack>
42
[557]43#include <hugo/graph_wrapper.h>
[602]44#include <bfs_dfs.h>
[555]45#include <hugo/invalid.h>
46#include <hugo/maps.h>
[478]47#include <for_each_macros.h>
48
[488]49/// \file
[615]50/// \brief Maximum flows.
51/// \ingroup galgs
[478]52
53namespace hugo {
54
[488]55
[602]56  //  ///\author Marton Makai, Jacint Szabo
[488]57  /// A class for computing max flows and related quantities.
[615]58  /// \ingroup galgs
59  template <typename Graph, typename Num,
60            typename CapMap=typename Graph::template EdgeMap<Num>,
[478]61            typename FlowMap=typename Graph::template EdgeMap<Num> >
62  class MaxFlow {
[615]63  protected:
[478]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;
[615]76    const CapMap* capacity;
[478]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;
[615]85    //level works as a bool map in augmenting path algorithms
[478]86    //and is used by bfs for storing reached information.
87    //In preflow, it shows levels of nodes.
[615]88    //typename Graph::template NodeMap<int> level;
89    typename Graph::template NodeMap<Num> excess;
[602]90    //   protected:
91    //     MaxFlow() { }
[615]92    //     void set(const Graph& _G, Node _s, Node _t, const CapMap& _capacity,
93    //       FlowMap& _flow)
[602]94    //       {
[615]95    //  g=&_G;
96    //  s=_s;
97    //  t=_t;
[602]98    //  capacity=&_capacity;
99    //  flow=&_flow;
100    //  n=_G.nodeNum;
[615]101    //  level.set (_G); //kellene vmi ilyesmi fv
[602]102    //  excess(_G,0); //itt is
103    //       }
[478]104
[615]105    // constants used for heuristics
106    static const int H0=20;
107    static const int H1=1;
108
[478]109  public:
[615]110
[586]111    ///\todo Document this.
112    ///\todo Maybe, it should be PRE_FLOW instead.
[615]113    ///- \c NO_FLOW means nothing,
[586]114    ///- \c ZERO_FLOW means something,
115    ///- \c GEN_FLOW means something else,
[615]116    ///- \c PRE_FLOW is something different.
[478]117    enum flowEnum{
[615]118      ZERO_FLOW,
119      GEN_FLOW,
120      PRE_FLOW,
121      NO_FLOW
[478]122    };
123
[615]124    MaxFlow(const Graph& _G, Node _s, Node _t, const CapMap& _capacity,
[478]125            FlowMap& _flow) :
[615]126      g(&_G), s(_s), t(_t), capacity(&_capacity),
[478]127      flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0) {}
128
[485]129    /// A max flow algorithm is run.
[615]130    /// \pre The flow have to satisfy the requirements
131    /// stated in fe.
132    void run(flowEnum fe=ZERO_FLOW) {
133      preflow(fe);
[478]134    }
[615]135
136    /// A preflow algorithm is run.
137    /// \pre The initial edge-map have to be a
[487]138    /// zero flow if \c fe is \c ZERO_FLOW,
[615]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.
[488]142    void preflow(flowEnum fe) {
[478]143      preflowPhase0(fe);
144      preflowPhase1();
145    }
146
[615]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);
[478]150
[485]151    /// Second phase of preflow.
[478]152    void preflowPhase1();
153
[615]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.
[487]157    /// The return value shows if the augmentation was succesful.
[478]158    bool augmentOnShortestPath();
159
[615]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
[485]163    /// residual graph of type \c Mutablegraph.
[487]164    /// The return value show sif the augmentation was succesful.
[478]165    template<typename MutableGraph> bool augmentOnBlockingFlow();
166
[615]167    /// The same as \c augmentOnBlockingFlow<MutableGraph> but the
[485]168    /// residual graph is not constructed physically.
[487]169    /// The return value shows if the augmentation was succesful.
[478]170    bool augmentOnBlockingFlow2();
171
172    /// Returns the actual flow value.
[615]173    /// More precisely, it returns the negative excess of s, thus
[478]174    /// this works also for preflows.
[615]175    Num flowValue() {
[478]176      Num a=0;
[615]177      FOR_EACH_INC_LOC(InEdgeIt, e, *g, t) a+=(*flow)[e];
178      FOR_EACH_INC_LOC(OutEdgeIt, e, *g, t) a-=(*flow)[e];
[478]179      return a;
180    }
181
[485]182    /// Should be used between preflowPhase0 and preflowPhase1.
[615]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
[485]186    /// for MinCut computation
[478]187    template<typename _CutMap>
188    void actMinCut(_CutMap& M) {
189      NodeIt v;
[485]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        }
[478]196      }
197    }
198
[615]199    /// The unique inclusionwise minimum cut is computed by
[485]200    /// processing a bfs from s in the residual graph.
[615]201    /// \pre flow have to be a max flow otherwise it will the whole node-set.
[478]202    template<typename _CutMap>
203    void minMinCut(_CutMap& M) {
[615]204
[478]205      std::queue<Node> queue;
[615]206
207      M.set(s,true);
[478]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          }
[615]221        }
[478]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          }
[615]230        }
[478]231      }
232    }
233
234
[615]235    /// The unique inclusionwise maximum cut is computed by
[485]236    /// processing a reverse bfs from t in the residual graph.
[615]237    /// \pre flow have to be a max flow otherwise it will be empty.
[478]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;
[615]247
248      M.set(t,false);
[478]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        }
[615]263
[478]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
[485]276    /// A minimum cut is computed.
[478]277    template<typename CutMap>
[485]278    void minCut(CutMap& M) { minMinCut(M); }
[478]279
[485]280    ///
[487]281    void resetSource(Node _s) { s=_s; }
282    ///
283    void resetTarget(Node _t) { t=_t; }
[615]284
[485]285    /// capacity-map is changed.
286    void resetCap(const CapMap& _cap) { capacity=&_cap; }
[615]287
288    /// flow-map is changed.
[485]289    void resetFlow(FlowMap& _flow) { flow=&_flow; }
[478]290
291
292  private:
293
294    int push(Node w, VecStack& active) {
[615]295
[478]296      int lev=level[w];
297      Num exc=excess[w];
298      int newlevel=n;       //bound on the next level of w
[615]299
[478]300      OutEdgeIt e;
301      for(g->first(e,w); g->valid(e); g->next(e)) {
[615]302
303        if ( (*flow)[e] >= (*capacity)[e] ) continue;
304        Node v=g->head(e);
305
[478]306        if( lev > level[v] ) { //Push is allowed now
[615]307
[478]308          if ( excess[v]<=0 && v!=t && v!=s ) {
309            int lev_v=level[v];
310            active[lev_v].push(v);
311          }
[615]312
[478]313          Num cap=(*capacity)[e];
314          Num flo=(*flow)[e];
315          Num remcap=cap-flo;
[615]316
[478]317          if ( remcap >= exc ) { //A nonsaturating push.
[615]318
[478]319            flow->set(e, flo+exc);
320            excess.set(v, excess[v]+exc);
321            exc=0;
[615]322            break;
323
[478]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];
[615]330      } //for out edges wv
331
332      if ( exc > 0 ) {
[478]333        InEdgeIt e;
334        for(g->first(e,w); g->valid(e); g->next(e)) {
[615]335
336          if( (*flow)[e] <= 0 ) continue;
337          Node v=g->tail(e);
338
[478]339          if( lev > level[v] ) { //Push is allowed now
[615]340
[478]341            if ( excess[v]<=0 && v!=t && v!=s ) {
342              int lev_v=level[v];
343              active[lev_v].push(v);
344            }
[615]345
[478]346            Num flo=(*flow)[e];
[615]347
[478]348            if ( flo >= exc ) { //A nonsaturating push.
[615]349
[478]350              flow->set(e, flo-exc);
351              excess.set(v, excess[v]+exc);
352              exc=0;
[615]353              break;
[478]354            } else {  //A saturating push.
[615]355
[478]356              excess.set(v, excess[v]+flo);
357              exc-=flo;
358              flow->set(e,0);
[615]359            }
[478]360          } else if ( newlevel > level[v] ) newlevel = level[v];
361        } //for in edges vw
[615]362
[478]363      } // if w still has excess after the out edge for cycle
[615]364
[478]365      excess.set(w, exc);
[615]366
[478]367      return newlevel;
[485]368    }
[478]369
370
[615]371    void preflowPreproc(flowEnum fe, VecStack& active,
372                        VecNode& level_list, NNMap& left, NNMap& right)
[602]373    {
[615]374      std::queue<Node> bfs_queue;
[478]375
[615]376      switch (fe) {
377      case ZERO_FLOW:
[602]378        {
379          //Reverse_bfs from t, to find the starting level.
380          level.set(t,0);
381          bfs_queue.push(t);
[615]382
[602]383          while (!bfs_queue.empty()) {
[615]384
385            Node v=bfs_queue.front();
[602]386            bfs_queue.pop();
387            int l=level[v]+1;
[615]388
[602]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          }
[615]402
[602]403          //the starting flow
404          OutEdgeIt e;
[615]405          for(g->first(e,s); g->valid(e); g->next(e))
[602]406            {
407              Num c=(*capacity)[e];
408              if ( c <= 0 ) continue;
409              Node w=g->head(e);
[615]410              if ( level[w] < n ) {
[602]411                if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
[615]412                flow->set(e, c);
[602]413                excess.set(w, excess[w]+c);
414              }
415            }
416          break;
417        }
[615]418
[602]419      case GEN_FLOW:
[615]420      case PRE_FLOW:
[602]421        {
[615]422          //Reverse_bfs from t in the residual graph,
[602]423          //to find the starting level.
424          level.set(t,0);
425          bfs_queue.push(t);
[615]426
[602]427          while (!bfs_queue.empty()) {
[615]428
429            Node v=bfs_queue.front();
[602]430            bfs_queue.pop();
431            int l=level[v]+1;
[615]432
[602]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            }
[615]446
[602]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          }
[615]461
462
[602]463          //the starting flow
464          OutEdgeIt e;
[615]465          for(g->first(e,s); g->valid(e); g->next(e))
[602]466            {
467              Num rem=(*capacity)[e]-(*flow)[e];
468              if ( rem <= 0 ) continue;
469              Node w=g->head(e);
[615]470              if ( level[w] < n ) {
[602]471                if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
[615]472                flow->set(e, (*capacity)[e]);
[602]473                excess.set(w, excess[w]+rem);
474              }
475            }
[615]476
[602]477          InEdgeIt f;
[615]478          for(g->first(f,s); g->valid(f); g->next(f))
[602]479            {
480              if ( (*flow)[f] <= 0 ) continue;
481              Node w=g->tail(f);
[615]482              if ( level[w] < n ) {
[602]483                if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
484                excess.set(w, excess[w]+(*flow)[f]);
[615]485                flow->set(f, 0);
[602]486              }
[615]487            }
[602]488          break;
[615]489        } //case PRE_FLOW
[602]490      }
491    } //preflowPreproc
[478]492
493
494
[615]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 )
[478]498    {
499
[615]500      Num lev=level[w];
501
[478]502      Node right_n=right[w];
503      Node left_n=left[w];
[615]504
[478]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 {
[615]511          level_list[lev]=right_n;
[478]512          left.set(right_n, INVALID);
[615]513        }
[478]514      } else {
515        if ( g->valid(left_n) ) {
516          right.set(left_n, INVALID);
[615]517        } else {
518          level_list[lev]=INVALID;
519        }
520      }
[478]521      //unlacing ends
[615]522
[478]523      if ( !g->valid(level_list[lev]) ) {
[615]524
[478]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            }
[615]537          }
[478]538        }
[615]539
[478]540        level.set(w,n);
541        b=lev-1;
542        k=b;
543        //gapping ends
[615]544
[478]545      } else {
[615]546
547        if ( newlevel == n ) level.set(w,n);
[478]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      }
[615]560
[478]561    } //relabel
562
563
[615]564    template<typename MapGraphWrapper>
[478]565    class DistanceMap {
566    protected:
567      const MapGraphWrapper* g;
[615]568      typename MapGraphWrapper::template NodeMap<int> dist;
[478]569    public:
570      DistanceMap(MapGraphWrapper& _g) : g(&_g), dist(*g, g->nodeNum()) { }
[615]571      void set(const typename MapGraphWrapper::Node& n, int a) {
572        dist.set(n, a);
[478]573      }
[615]574      int operator[](const typename MapGraphWrapper::Node& n)
[485]575      { return dist[n]; }
[615]576      //       int get(const typename MapGraphWrapper::Node& n) const {
[485]577      //        return dist[n]; }
[615]578      //       bool get(const typename MapGraphWrapper::Edge& e) const {
[485]579      //        return (dist.get(g->tail(e))<dist.get(g->head(e))); }
[615]580      bool operator[](const typename MapGraphWrapper::Edge& e) const {
581        return (dist[g->tail(e)]<dist[g->head(e)]);
[478]582      }
583    };
[615]584
[478]585  };
586
587
588  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
[615]589  void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase0( flowEnum fe )
[478]590  {
[615]591
592    int heur0=(int)(H0*n);  //time while running 'bound decrease'
[485]593    int heur1=(int)(H1*n);  //time while running 'highest label'
594    int heur=heur1;         //starting time interval (#of relabels)
595    int numrelabel=0;
[615]596
597    bool what_heur=1;
[485]598    //It is 0 in case 'bound decrease' and 1 in case 'highest label'
[478]599
[615]600    bool end=false;
601    //Needed for 'bound decrease', true means no active nodes are above bound
602    //b.
[478]603
[485]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
[615]606
[485]607    VecStack active(n);
[615]608
[485]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.
[478]613
[485]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
[615]617
618    switch (fe) {
619    case PRE_FLOW:
[485]620      {
[615]621        //computing the excess
[485]622        NodeIt v;
623        for(g->first(v); g->valid(v); g->next(v)) {
[478]624          Num exc=0;
[615]625
[478]626          InEdgeIt e;
[485]627          for(g->first(e,v); g->valid(e); g->next(e)) exc+=(*flow)[e];
[478]628          OutEdgeIt f;
[485]629          for(g->first(f,v); g->valid(f); g->next(f)) exc-=(*flow)[f];
[615]630
631          excess.set(v,exc);
632
[485]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);
[478]636        }
637        break;
638      }
[485]639    case GEN_FLOW:
640      {
[615]641        //computing the excess of t
[485]642        Num exc=0;
[615]643
[485]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];
[615]648
649        excess.set(t,exc);
650
[485]651        break;
652      }
[615]653    default:;
[485]654    }
[615]655
656    preflowPreproc(fe, active, level_list, left, right);
657    //End of preprocessing
658
659
[485]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      }
[615]668
669      if ( active[b].empty() ) --b;
[485]670      else {
[615]671        end=false;
[485]672        Node w=active[b].top();
673        active[b].pop();
674        int newlevel=push(w,active);
[615]675        if ( excess[w] > 0 ) relabel(w, newlevel, active, level_list,
[485]676                                     left, right, b, k, what_heur);
[615]677
678        ++numrelabel;
[485]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;
[615]688            b=k;
[485]689          }
[478]690        }
[615]691      }
692    }
[485]693  }
[478]694
695
696
697  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
[615]698  void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase1()
[478]699  {
[615]700
[485]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
[615]703
[485]704    VecStack active(n);
705    level.set(s,0);
706    std::queue<Node> bfs_queue;
707    bfs_queue.push(s);
[615]708
[485]709    while (!bfs_queue.empty()) {
[615]710
711      Node v=bfs_queue.front();
[485]712      bfs_queue.pop();
713      int l=level[v]+1;
[615]714
[485]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);
[615]719        if ( level[u] >= n ) {
[485]720          bfs_queue.push(u);
721          level.set(u, l);
722          if ( excess[u] > 0 ) active[l].push(u);
[478]723        }
724      }
[615]725
[485]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);
[615]730        if ( level[u] >= n ) {
[485]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;
[478]738
[485]739    while ( true ) {
[615]740
[485]741      if ( b == 0 ) break;
[478]742
[615]743      if ( active[b].empty() ) --b;
[485]744      else {
745        Node w=active[b].top();
746        active[b].pop();
[615]747        int newlevel=push(w,active);
[478]748
[485]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  }
[478]758
759
760
761  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
[615]762  bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath()
[478]763  {
[485]764    ResGW res_graph(*g, *capacity, *flow);
765    bool _augment=false;
[615]766
[485]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);
[615]771
772    typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
[485]773    pred.set(s, INVALID);
[615]774
[485]775    typename ResGW::template NodeMap<Num> free(res_graph);
[615]776
[485]777    //searching for augmenting path
[615]778    while ( !bfs.finished() ) {
[485]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 {
[615]787          free.set(w, res_graph.resCap(e));
[478]788        }
[485]789        if (res_graph.head(e)==t) { _augment=true; break; }
790      }
[615]791
[485]792      ++bfs;
793    } //end of searching augmenting path
[478]794
[485]795    if (_augment) {
796      Node n=t;
797      Num augment_value=free[t];
[615]798      while (res_graph.valid(pred[n])) {
[485]799        ResGWEdge e=pred[n];
[615]800        res_graph.augment(e, augment_value);
[485]801        n=res_graph.tail(e);
[478]802      }
[485]803    }
[478]804
[485]805    return _augment;
806  }
[478]807
808
809
810
811
812
813
814  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
[615]815  template<typename MutableGraph>
816  bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow()
817  {
[485]818    typedef MutableGraph MG;
819    bool _augment=false;
[478]820
[485]821    ResGW res_graph(*g, *capacity, *flow);
[478]822
[485]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);
[615]828    typename ResGW::template NodeMap<int>
[485]829      dist(res_graph); //filled up with 0's
[478]830
[485]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;
[615]834    typename ResGW::template NodeMap<typename MG::Node>
[485]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());
[478]840      }
[485]841    }
[478]842
[485]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);
[478]847
[615]848    while ( !bfs.finished() ) {
[485]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);
[615]853          typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)],
854                                        res_graph_to_F[res_graph.head(e)]);
[485]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)) {
[615]861            typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)],
862                                          res_graph_to_F[res_graph.head(e)]);
[478]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        }
[485]869      }
870      ++bfs;
871    } //computing distances from s in the residual graph
[478]872
[485]873    bool __augment=true;
[478]874
[485]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
[478]882
[485]883      typename MG::template NodeMap<Num> free(F);
[478]884
[615]885      dfs.pushAndSetReached(sF);
[485]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 {
[615]896              free.set(w, residual_capacity[dfs]);
[485]897            }
[615]898            if (w==tF) {
899              __augment=true;
[485]900              _augment=true;
[615]901              break;
[485]902            }
[615]903
[485]904          } else {
905            F.erase(/*typename MG::OutEdgeIt*/(dfs));
906          }
[615]907        }
[485]908      }
909
910      if (__augment) {
911        typename MG::Node n=tF;
912        Num augment_value=free[tF];
[615]913        while (F.valid(pred[n])) {
[485]914          typename MG::Edge e=pred[n];
[615]915          res_graph.augment(original_edge[e], augment_value);
[485]916          n=F.tail(e);
[615]917          if (residual_capacity[e]==augment_value)
918            F.erase(e);
919          else
[485]920            residual_capacity.set(e, residual_capacity[e]-augment_value);
[478]921        }
[485]922      }
[615]923
[485]924    }
[615]925
[485]926    return _augment;
927  }
[478]928
929
930
931
932  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
[615]933  bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow2()
[478]934  {
[485]935    bool _augment=false;
[478]936
[485]937    ResGW res_graph(*g, *capacity, *flow);
[615]938
[485]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);
[478]942
[485]943    bfs.pushAndSetReached(s);
944    DistanceMap<ResGW> dist(res_graph);
[615]945    while ( !bfs.finished() ) {
[485]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
[478]952
953      //Subgraph containing the edges on some shortest paths
[485]954    ConstMap<typename ResGW::Node, bool> true_map(true);
[615]955    typedef SubGraphWrapper<ResGW, ConstMap<typename ResGW::Node, bool>,
[485]956      DistanceMap<ResGW> > FilterResGW;
957    FilterResGW filter_res_graph(res_graph, true_map, dist);
[478]958
[615]959    //Subgraph, which is able to delete edges which are already
[485]960    //met by the dfs
[615]961    typename FilterResGW::template NodeMap<typename FilterResGW::OutEdgeIt>
[485]962      first_out_edges(filter_res_graph);
963    typename FilterResGW::NodeIt v;
[615]964    for(filter_res_graph.first(v); filter_res_graph.valid(v);
965        filter_res_graph.next(v))
[478]966      {
967        typename FilterResGW::OutEdgeIt e;
968        filter_res_graph.first(e, v);
969        first_out_edges.set(v, e);
970      }
[485]971    typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
972      template NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
973    ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
[478]974
[485]975    bool __augment=true;
[478]976
[485]977    while (__augment) {
[478]978
[485]979      __augment=false;
980      //computing blocking flow with dfs
[615]981      DfsIterator< ErasingResGW,
982        typename ErasingResGW::template NodeMap<bool> >
[485]983        dfs(erasing_res_graph);
984      typename ErasingResGW::
[615]985        template NodeMap<typename ErasingResGW::OutEdgeIt>
986        pred(erasing_res_graph);
[485]987      pred.set(s, INVALID);
988      //invalid iterators for sources
[478]989
[615]990      typename ErasingResGW::template NodeMap<Num>
[485]991        free1(erasing_res_graph);
[478]992
[615]993      dfs.pushAndSetReached
994        ///\bug hugo 0.2
995        (typename ErasingResGW::Node
996         (typename FilterResGW::Node
997          (typename ResGW::Node(s)
998           )
999          )
1000         );
[485]1001      while (!dfs.finished()) {
1002        ++dfs;
[615]1003        if (erasing_res_graph.valid(typename ErasingResGW::OutEdgeIt(dfs)))
1004          {
[478]1005            if (dfs.isBNodeNewlyReached()) {
[615]1006
[478]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])) {
[615]1012                free1.set
1013                  (w, std::min(free1[v], res_graph.resCap
1014                               (typename ErasingResGW::OutEdgeIt(dfs))));
[478]1015              } else {
[615]1016                free1.set
1017                  (w, res_graph.resCap
1018                   (typename ErasingResGW::OutEdgeIt(dfs)));
[478]1019              }
[615]1020
1021              if (w==t) {
1022                __augment=true;
[478]1023                _augment=true;
[615]1024                break;
[478]1025              }
1026            } else {
1027              erasing_res_graph.erase(dfs);
1028            }
1029          }
[615]1030      }
[478]1031
[485]1032      if (__augment) {
[615]1033        typename ErasingResGW::Node
1034          n=typename FilterResGW::Node(typename ResGW::Node(t));
[485]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];
[615]1045        while (erasing_res_graph.valid(pred[n])) {
[485]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);
[478]1051        }
1052      }
[615]1053
1054    } //while (__augment)
1055
[485]1056    return _augment;
1057  }
[478]1058
1059
1060} //namespace hugo
1061
[480]1062#endif //HUGO_MAX_FLOW_H
[478]1063
1064
1065
1066
Note: See TracBrowser for help on using the repository browser.