COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/jacint/max_flow.h @ 615:b6b31b75b522

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

docs, max_flow improvments

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