COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/jacint/max_flow.h @ 520:e4a6300616f9

Last change on this file since 520:e4a6300616f9 was 510:72143568cadc, checked in by marci, 21 years ago

matching, flows

File size: 27.0 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#define H0 20
40#define H1 1
41
42#include <vector>
43#include <queue>
44#include <stack>
45
46#include <graph_wrapper.h>
47#include <bfs_iterator.h>
48#include <invalid.h>
49#include <maps.h>
50#include <for_each_macros.h>
51
52/// \file
53/// \brief Dimacs file format reader.
54
55namespace hugo {
56
57
58//  ///\author Marton Makai, Jacint Szabo
59  /// A class for computing max flows and related quantities.
60  template <typename Graph, typename Num,
61            typename CapMap=typename Graph::template EdgeMap<Num>,
62            typename FlowMap=typename Graph::template EdgeMap<Num> >
63  class MaxFlow {
64   
65    typedef typename Graph::Node Node;
66    typedef typename Graph::NodeIt NodeIt;
67    typedef typename Graph::OutEdgeIt OutEdgeIt;
68    typedef typename Graph::InEdgeIt InEdgeIt;
69
70    typedef typename std::vector<std::stack<Node> > VecStack;
71    typedef typename Graph::template NodeMap<Node> NNMap;
72    typedef typename std::vector<Node> VecNode;
73
74    const Graph* g;
75    Node s;
76    Node t;
77    const CapMap* capacity; 
78    FlowMap* flow;
79    int n;      //the number of nodes of G
80    typedef ResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;
81    typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
82    typedef typename ResGW::Edge ResGWEdge;
83    //typedef typename ResGW::template NodeMap<bool> ReachedMap;
84    typedef typename Graph::template NodeMap<int> ReachedMap;
85    ReachedMap level;
86    //level works as a bool map in augmenting path algorithms
87    //and is used by bfs for storing reached information.
88    //In preflow, it shows levels of nodes.
89    //typename Graph::template NodeMap<int> level;   
90    typename Graph::template NodeMap<Num> excess;
91//   protected:
92//     MaxFlow() { }
93//     void set(const Graph& _G, Node _s, Node _t, const CapMap& _capacity,
94//           FlowMap& _flow)
95//       {
96//      g=&_G;
97//      s=_s;
98//      t=_t;
99//      capacity=&_capacity;
100//      flow=&_flow;
101//      n=_G.nodeNum;
102//      level.set (_G); //kellene vmi ilyesmi fv
103//      excess(_G,0); //itt is
104//       }
105
106  public:
107 
108    ///\todo Document this
109    enum flowEnum{
110      ZERO_FLOW=0,
111      GEN_FLOW=1,
112      PREFLOW=2
113    };
114
115    MaxFlow(const Graph& _G, Node _s, Node _t, const CapMap& _capacity,
116            FlowMap& _flow) :
117      g(&_G), s(_s), t(_t), capacity(&_capacity),
118      flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0) {}
119
120    /// A max flow algorithm is run.
121    ///\pre the flow have to be 0 at the beginning.
122    void run() {
123      preflow(ZERO_FLOW);
124    }
125   
126    /// A preflow algorithm is run.
127    ///\pre The initial edge-map have to be a
128    /// zero flow if \c fe is \c ZERO_FLOW,
129    /// a flow if \c fe is \c GEN_FLOW,
130    /// and a pre-flow it is \c PREFLOW.
131    void preflow(flowEnum fe) {
132      preflowPhase0(fe);
133      preflowPhase1();
134    }
135
136    /// Run the first phase of preflow, starting from a 0 flow, from a flow,
137    /// or from a preflow, according to \c fe.
138    void preflowPhase0( flowEnum fe );
139
140    /// Second phase of preflow.
141    void preflowPhase1();
142
143    /// Starting from a flow, this method searches for an augmenting path
144    /// according to the Edmonds-Karp algorithm
145    /// and augments the flow on if any.
146    /// The return value shows if the augmentation was succesful.
147    bool augmentOnShortestPath();
148
149    /// Starting from a flow, this method searches for an augmenting blockin
150    /// flow according to Dinits' algorithm and augments the flow on if any.
151    /// The blocking flow is computed in a physically constructed
152    /// residual graph of type \c Mutablegraph.
153    /// The return value show sif the augmentation was succesful.
154    template<typename MutableGraph> bool augmentOnBlockingFlow();
155
156    /// The same as \c augmentOnBlockingFlow<MutableGraph> but the
157    /// residual graph is not constructed physically.
158    /// The return value shows if the augmentation was succesful.
159    bool augmentOnBlockingFlow2();
160
161    /// Returns the actual flow value.
162    /// More precisely, it returns the negative excess of s, thus
163    /// this works also for preflows.
164    Num flowValue() {
165      Num a=0;
166      FOR_EACH_INC_LOC(OutEdgeIt, e, *g, s) a+=(*flow)[e];
167      FOR_EACH_INC_LOC(InEdgeIt, e, *g, s) a-=(*flow)[e];
168      return a;
169    }
170
171    /// Should be used between preflowPhase0 and preflowPhase1.
172    ///\todo We have to make some status variable which shows the actual state
173    /// of the class. This enables us to determine which methods are valid
174    /// for MinCut computation
175    template<typename _CutMap>
176    void actMinCut(_CutMap& M) {
177      NodeIt v;
178      for(g->first(v); g->valid(v); g->next(v)) {
179        if ( level[v] < n ) {
180          M.set(v,false);
181        } else {
182          M.set(v,true);
183        }
184      }
185    }
186
187    /// The unique inclusionwise minimum cut is computed by
188    /// processing a bfs from s in the residual graph.
189    ///\pre flow have to be a max flow otherwise it will the whole node-set.
190    template<typename _CutMap>
191    void minMinCut(_CutMap& M) {
192   
193      std::queue<Node> queue;
194     
195      M.set(s,true);     
196      queue.push(s);
197
198      while (!queue.empty()) {
199        Node w=queue.front();
200        queue.pop();
201
202        OutEdgeIt e;
203        for(g->first(e,w) ; g->valid(e); g->next(e)) {
204          Node v=g->head(e);
205          if (!M[v] && (*flow)[e] < (*capacity)[e] ) {
206            queue.push(v);
207            M.set(v, true);
208          }
209        }
210
211        InEdgeIt f;
212        for(g->first(f,w) ; g->valid(f); g->next(f)) {
213          Node v=g->tail(f);
214          if (!M[v] && (*flow)[f] > 0 ) {
215            queue.push(v);
216            M.set(v, true);
217          }
218        }
219      }
220    }
221
222
223    /// The unique inclusionwise maximum cut is computed by
224    /// processing a reverse bfs from t in the residual graph.
225    ///\pre flow have to be a max flow otherwise it will be empty.
226    template<typename _CutMap>
227    void maxMinCut(_CutMap& M) {
228
229      NodeIt v;
230      for(g->first(v) ; g->valid(v); g->next(v)) {
231        M.set(v, true);
232      }
233
234      std::queue<Node> queue;
235     
236      M.set(t,false);       
237      queue.push(t);
238
239      while (!queue.empty()) {
240        Node w=queue.front();
241        queue.pop();
242
243
244        InEdgeIt e;
245        for(g->first(e,w) ; g->valid(e); g->next(e)) {
246          Node v=g->tail(e);
247          if (M[v] && (*flow)[e] < (*capacity)[e] ) {
248            queue.push(v);
249            M.set(v, false);
250          }
251        }
252       
253        OutEdgeIt f;
254        for(g->first(f,w) ; g->valid(f); g->next(f)) {
255          Node v=g->head(f);
256          if (M[v] && (*flow)[f] > 0 ) {
257            queue.push(v);
258            M.set(v, false);
259          }
260        }
261      }
262    }
263
264
265    /// A minimum cut is computed.
266    template<typename CutMap>
267    void minCut(CutMap& M) { minMinCut(M); }
268
269    ///
270    void resetSource(Node _s) { s=_s; }
271    ///
272    void resetTarget(Node _t) { t=_t; }
273   
274    /// capacity-map is changed.
275    void resetCap(const CapMap& _cap) { capacity=&_cap; }
276   
277    /// flow-map is changed.
278    void resetFlow(FlowMap& _flow) { flow=&_flow; }
279
280
281  private:
282
283    int push(Node w, VecStack& active) {
284     
285      int lev=level[w];
286      Num exc=excess[w];
287      int newlevel=n;       //bound on the next level of w
288         
289      OutEdgeIt e;
290      for(g->first(e,w); g->valid(e); g->next(e)) {
291           
292        if ( (*flow)[e] >= (*capacity)[e] ) continue;
293        Node v=g->head(e);           
294           
295        if( lev > level[v] ) { //Push is allowed now
296         
297          if ( excess[v]<=0 && v!=t && v!=s ) {
298            int lev_v=level[v];
299            active[lev_v].push(v);
300          }
301         
302          Num cap=(*capacity)[e];
303          Num flo=(*flow)[e];
304          Num remcap=cap-flo;
305         
306          if ( remcap >= exc ) { //A nonsaturating push.
307           
308            flow->set(e, flo+exc);
309            excess.set(v, excess[v]+exc);
310            exc=0;
311            break;
312           
313          } else { //A saturating push.
314            flow->set(e, cap);
315            excess.set(v, excess[v]+remcap);
316            exc-=remcap;
317          }
318        } else if ( newlevel > level[v] ) newlevel = level[v];
319      } //for out edges wv
320     
321      if ( exc > 0 ) { 
322        InEdgeIt e;
323        for(g->first(e,w); g->valid(e); g->next(e)) {
324         
325          if( (*flow)[e] <= 0 ) continue;
326          Node v=g->tail(e);
327         
328          if( lev > level[v] ) { //Push is allowed now
329           
330            if ( excess[v]<=0 && v!=t && v!=s ) {
331              int lev_v=level[v];
332              active[lev_v].push(v);
333            }
334           
335            Num flo=(*flow)[e];
336           
337            if ( flo >= exc ) { //A nonsaturating push.
338             
339              flow->set(e, flo-exc);
340              excess.set(v, excess[v]+exc);
341              exc=0;
342              break;
343            } else {  //A saturating push.
344             
345              excess.set(v, excess[v]+flo);
346              exc-=flo;
347              flow->set(e,0);
348            } 
349          } else if ( newlevel > level[v] ) newlevel = level[v];
350        } //for in edges vw
351       
352      } // if w still has excess after the out edge for cycle
353     
354      excess.set(w, exc);
355     
356      return newlevel;
357    }
358
359
360    void preflowPreproc ( flowEnum fe, VecStack& active,
361                          VecNode& level_list, NNMap& left, NNMap& right ) {
362
363                            std::queue<Node> bfs_queue;
364     
365                            switch ( fe ) {
366                            case ZERO_FLOW:
367                              {
368                                //Reverse_bfs from t, to find the starting level.
369                                level.set(t,0);
370                                bfs_queue.push(t);
371       
372                                while (!bfs_queue.empty()) {
373           
374                                  Node v=bfs_queue.front();     
375                                  bfs_queue.pop();
376                                  int l=level[v]+1;
377           
378                                  InEdgeIt e;
379                                  for(g->first(e,v); g->valid(e); g->next(e)) {
380                                    Node w=g->tail(e);
381                                    if ( level[w] == n && w != s ) {
382                                      bfs_queue.push(w);
383                                      Node first=level_list[l];
384                                      if ( g->valid(first) ) left.set(first,w);
385                                      right.set(w,first);
386                                      level_list[l]=w;
387                                      level.set(w, l);
388                                    }
389                                  }
390                                }
391         
392                                //the starting flow
393                                OutEdgeIt e;
394                                for(g->first(e,s); g->valid(e); g->next(e))
395                                  {
396                                    Num c=(*capacity)[e];
397                                    if ( c <= 0 ) continue;
398                                    Node w=g->head(e);
399                                    if ( level[w] < n ) {         
400                                      if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
401                                      flow->set(e, c);
402                                      excess.set(w, excess[w]+c);
403                                    }
404                                  }
405                                break;
406                              }
407       
408                            case GEN_FLOW:
409                            case PREFLOW:
410                              {
411                                //Reverse_bfs from t in the residual graph,
412                                //to find the starting level.
413                                level.set(t,0);
414                                bfs_queue.push(t);
415         
416                                while (!bfs_queue.empty()) {
417           
418                                  Node v=bfs_queue.front();     
419                                  bfs_queue.pop();
420                                  int l=level[v]+1;
421           
422                                  InEdgeIt e;
423                                  for(g->first(e,v); g->valid(e); g->next(e)) {
424                                    if ( (*capacity)[e] <= (*flow)[e] ) continue;
425                                    Node w=g->tail(e);
426                                    if ( level[w] == n && w != s ) {
427                                      bfs_queue.push(w);
428                                      Node first=level_list[l];
429                                      if ( g->valid(first) ) left.set(first,w);
430                                      right.set(w,first);
431                                      level_list[l]=w;
432                                      level.set(w, l);
433                                    }
434                                  }
435           
436                                  OutEdgeIt f;
437                                  for(g->first(f,v); g->valid(f); g->next(f)) {
438                                    if ( 0 >= (*flow)[f] ) continue;
439                                    Node w=g->head(f);
440                                    if ( level[w] == n && w != s ) {
441                                      bfs_queue.push(w);
442                                      Node first=level_list[l];
443                                      if ( g->valid(first) ) left.set(first,w);
444                                      right.set(w,first);
445                                      level_list[l]=w;
446                                      level.set(w, l);
447                                    }
448                                  }
449                                }
450         
451         
452                                //the starting flow
453                                OutEdgeIt e;
454                                for(g->first(e,s); g->valid(e); g->next(e))
455                                  {
456                                    Num rem=(*capacity)[e]-(*flow)[e];
457                                    if ( rem <= 0 ) continue;
458                                    Node w=g->head(e);
459                                    if ( level[w] < n ) {         
460                                      if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
461                                      flow->set(e, (*capacity)[e]);
462                                      excess.set(w, excess[w]+rem);
463                                    }
464                                  }
465         
466                                InEdgeIt f;
467                                for(g->first(f,s); g->valid(f); g->next(f))
468                                  {
469                                    if ( (*flow)[f] <= 0 ) continue;
470                                    Node w=g->tail(f);
471                                    if ( level[w] < n ) {         
472                                      if ( excess[w] <= 0 && w!=t ) active[level[w]].push(w);
473                                      excess.set(w, excess[w]+(*flow)[f]);
474                                      flow->set(f, 0);
475                                    }
476                                  } 
477                                break;
478                              } //case PREFLOW
479                            }
480                          } //preflowPreproc
481
482
483
484    void relabel(Node w, int newlevel, VecStack& active, 
485                 VecNode& level_list, NNMap& left,
486                 NNMap& right, int& b, int& k, bool what_heur )
487    {
488
489      Num lev=level[w];
490     
491      Node right_n=right[w];
492      Node left_n=left[w];
493     
494      //unlacing starts
495      if ( g->valid(right_n) ) {
496        if ( g->valid(left_n) ) {
497          right.set(left_n, right_n);
498          left.set(right_n, left_n);
499        } else {
500          level_list[lev]=right_n;   
501          left.set(right_n, INVALID);
502        }
503      } else {
504        if ( g->valid(left_n) ) {
505          right.set(left_n, INVALID);
506        } else {
507          level_list[lev]=INVALID;   
508        }
509      }
510      //unlacing ends
511               
512      if ( !g->valid(level_list[lev]) ) {
513             
514        //gapping starts
515        for (int i=lev; i!=k ; ) {
516          Node v=level_list[++i];
517          while ( g->valid(v) ) {
518            level.set(v,n);
519            v=right[v];
520          }
521          level_list[i]=INVALID;
522          if ( !what_heur ) {
523            while ( !active[i].empty() ) {
524              active[i].pop();    //FIXME: ezt szebben kene
525            }
526          }         
527        }
528       
529        level.set(w,n);
530        b=lev-1;
531        k=b;
532        //gapping ends
533       
534      } else {
535       
536        if ( newlevel == n ) level.set(w,n);
537        else {
538          level.set(w,++newlevel);
539          active[newlevel].push(w);
540          if ( what_heur ) b=newlevel;
541          if ( k < newlevel ) ++k;      //now k=newlevel
542          Node first=level_list[newlevel];
543          if ( g->valid(first) ) left.set(first,w);
544          right.set(w,first);
545          left.set(w,INVALID);
546          level_list[newlevel]=w;
547        }
548      }
549     
550    } //relabel
551
552
553    template<typename MapGraphWrapper>
554    class DistanceMap {
555    protected:
556      const MapGraphWrapper* g;
557      typename MapGraphWrapper::template NodeMap<int> dist;
558    public:
559      DistanceMap(MapGraphWrapper& _g) : g(&_g), dist(*g, g->nodeNum()) { }
560      void set(const typename MapGraphWrapper::Node& n, int a) {
561        dist.set(n, a);
562      }
563      int operator[](const typename MapGraphWrapper::Node& n)
564      { return dist[n]; }
565      //       int get(const typename MapGraphWrapper::Node& n) const {
566      //        return dist[n]; }
567      //       bool get(const typename MapGraphWrapper::Edge& e) const {
568      //        return (dist.get(g->tail(e))<dist.get(g->head(e))); }
569      bool operator[](const typename MapGraphWrapper::Edge& e) const {
570        return (dist[g->tail(e)]<dist[g->head(e)]);
571      }
572    };
573   
574  };
575
576
577  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
578  void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase0( flowEnum fe )
579  {
580     
581    int heur0=(int)(H0*n);  //time while running 'bound decrease'
582    int heur1=(int)(H1*n);  //time while running 'highest label'
583    int heur=heur1;         //starting time interval (#of relabels)
584    int numrelabel=0;
585     
586    bool what_heur=1;       
587    //It is 0 in case 'bound decrease' and 1 in case 'highest label'
588
589    bool end=false;     
590    //Needed for 'bound decrease', true means no active nodes are above bound b.
591
592    int k=n-2;  //bound on the highest level under n containing a node
593    int b=k;    //bound on the highest level under n of an active node
594     
595    VecStack active(n);
596     
597    NNMap left(*g, INVALID);
598    NNMap right(*g, INVALID);
599    VecNode level_list(n,INVALID);
600    //List of the nodes in level i<n, set to n.
601
602    NodeIt v;
603    for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
604    //setting each node to level n
605     
606    switch ( fe ) {
607    case PREFLOW:
608      {
609        //counting the excess
610        NodeIt v;
611        for(g->first(v); g->valid(v); g->next(v)) {
612          Num exc=0;
613         
614          InEdgeIt e;
615          for(g->first(e,v); g->valid(e); g->next(e)) exc+=(*flow)[e];
616          OutEdgeIt f;
617          for(g->first(f,v); g->valid(f); g->next(f)) exc-=(*flow)[f];
618           
619          excess.set(v,exc);     
620           
621          //putting the active nodes into the stack
622          int lev=level[v];
623          if ( exc > 0 && lev < n && v != t ) active[lev].push(v);
624        }
625        break;
626      }
627    case GEN_FLOW:
628      {
629        //Counting the excess of t
630        Num exc=0;
631         
632        InEdgeIt e;
633        for(g->first(e,t); g->valid(e); g->next(e)) exc+=(*flow)[e];
634        OutEdgeIt f;
635        for(g->first(f,t); g->valid(f); g->next(f)) exc-=(*flow)[f];
636         
637        excess.set(t,exc);     
638         
639        break;
640      }
641    default:
642      break;
643    }
644     
645    preflowPreproc( fe, active, level_list, left, right );
646    //End of preprocessing
647     
648     
649    //Push/relabel on the highest level active nodes.
650    while ( true ) {
651      if ( b == 0 ) {
652        if ( !what_heur && !end && k > 0 ) {
653          b=k;
654          end=true;
655        } else break;
656      }
657       
658      if ( active[b].empty() ) --b;
659      else {
660        end=false; 
661        Node w=active[b].top();
662        active[b].pop();
663        int newlevel=push(w,active);
664        if ( excess[w] > 0 ) relabel(w, newlevel, active, level_list,
665                                     left, right, b, k, what_heur);
666         
667        ++numrelabel;
668        if ( numrelabel >= heur ) {
669          numrelabel=0;
670          if ( what_heur ) {
671            what_heur=0;
672            heur=heur0;
673            end=false;
674          } else {
675            what_heur=1;
676            heur=heur1;
677            b=k;
678          }
679        }
680      }
681    }
682  }
683
684
685
686  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
687  void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase1()
688  {
689     
690    int k=n-2;  //bound on the highest level under n containing a node
691    int b=k;    //bound on the highest level under n of an active node
692     
693    VecStack active(n);
694    level.set(s,0);
695    std::queue<Node> bfs_queue;
696    bfs_queue.push(s);
697           
698    while (!bfs_queue.empty()) {
699       
700      Node v=bfs_queue.front();
701      bfs_queue.pop();
702      int l=level[v]+1;
703             
704      InEdgeIt e;
705      for(g->first(e,v); g->valid(e); g->next(e)) {
706        if ( (*capacity)[e] <= (*flow)[e] ) continue;
707        Node u=g->tail(e);
708        if ( level[u] >= n ) {
709          bfs_queue.push(u);
710          level.set(u, l);
711          if ( excess[u] > 0 ) active[l].push(u);
712        }
713      }
714       
715      OutEdgeIt f;
716      for(g->first(f,v); g->valid(f); g->next(f)) {
717        if ( 0 >= (*flow)[f] ) continue;
718        Node u=g->head(f);
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    b=n-2;
727
728    while ( true ) {
729       
730      if ( b == 0 ) break;
731
732      if ( active[b].empty() ) --b;
733      else {
734        Node w=active[b].top();
735        active[b].pop();
736        int newlevel=push(w,active);     
737
738        //relabel
739        if ( excess[w] > 0 ) {
740          level.set(w,++newlevel);
741          active[newlevel].push(w);
742          b=newlevel;
743        }
744      }  // if stack[b] is nonempty
745    } // while(true)
746  }
747
748
749
750  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
751  bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath()
752  {
753    ResGW res_graph(*g, *capacity, *flow);
754    bool _augment=false;
755     
756    //ReachedMap level(res_graph);
757    FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
758    BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
759    bfs.pushAndSetReached(s);
760       
761    typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
762    pred.set(s, INVALID);
763     
764    typename ResGW::template NodeMap<Num> free(res_graph);
765       
766    //searching for augmenting path
767    while ( !bfs.finished() ) {
768      ResGWOutEdgeIt e=bfs;
769      if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
770        Node v=res_graph.tail(e);
771        Node w=res_graph.head(e);
772        pred.set(w, e);
773        if (res_graph.valid(pred[v])) {
774          free.set(w, std::min(free[v], res_graph.resCap(e)));
775        } else {
776          free.set(w, res_graph.resCap(e));
777        }
778        if (res_graph.head(e)==t) { _augment=true; break; }
779      }
780       
781      ++bfs;
782    } //end of searching augmenting path
783
784    if (_augment) {
785      Node n=t;
786      Num augment_value=free[t];
787      while (res_graph.valid(pred[n])) {
788        ResGWEdge e=pred[n];
789        res_graph.augment(e, augment_value);
790        n=res_graph.tail(e);
791      }
792    }
793
794    return _augment;
795  }
796
797
798
799
800
801
802
803
804
805  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
806  template<typename MutableGraph>
807  bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow()
808  {     
809    typedef MutableGraph MG;
810    bool _augment=false;
811
812    ResGW res_graph(*g, *capacity, *flow);
813
814    //bfs for distances on the residual graph
815    //ReachedMap level(res_graph);
816    FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
817    BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
818    bfs.pushAndSetReached(s);
819    typename ResGW::template NodeMap<int>
820      dist(res_graph); //filled up with 0's
821
822    //F will contain the physical copy of the residual graph
823    //with the set of edges which are on shortest paths
824    MG F;
825    typename ResGW::template NodeMap<typename MG::Node>
826      res_graph_to_F(res_graph);
827    {
828      typename ResGW::NodeIt n;
829      for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
830        res_graph_to_F.set(n, F.addNode());
831      }
832    }
833
834    typename MG::Node sF=res_graph_to_F[s];
835    typename MG::Node tF=res_graph_to_F[t];
836    typename MG::template EdgeMap<ResGWEdge> original_edge(F);
837    typename MG::template EdgeMap<Num> residual_capacity(F);
838
839    while ( !bfs.finished() ) {
840      ResGWOutEdgeIt e=bfs;
841      if (res_graph.valid(e)) {
842        if (bfs.isBNodeNewlyReached()) {
843          dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
844          typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
845          original_edge.update();
846          original_edge.set(f, e);
847          residual_capacity.update();
848          residual_capacity.set(f, res_graph.resCap(e));
849        } else {
850          if (dist[res_graph.head(e)]==(dist[res_graph.tail(e)]+1)) {
851            typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
852            original_edge.update();
853            original_edge.set(f, e);
854            residual_capacity.update();
855            residual_capacity.set(f, res_graph.resCap(e));
856          }
857        }
858      }
859      ++bfs;
860    } //computing distances from s in the residual graph
861
862    bool __augment=true;
863
864    while (__augment) {
865      __augment=false;
866      //computing blocking flow with dfs
867      DfsIterator< MG, typename MG::template NodeMap<bool> > dfs(F);
868      typename MG::template NodeMap<typename MG::Edge> pred(F);
869      pred.set(sF, INVALID);
870      //invalid iterators for sources
871
872      typename MG::template NodeMap<Num> free(F);
873
874      dfs.pushAndSetReached(sF);     
875      while (!dfs.finished()) {
876        ++dfs;
877        if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
878          if (dfs.isBNodeNewlyReached()) {
879            typename MG::Node v=F.aNode(dfs);
880            typename MG::Node w=F.bNode(dfs);
881            pred.set(w, dfs);
882            if (F.valid(pred[v])) {
883              free.set(w, std::min(free[v], residual_capacity[dfs]));
884            } else {
885              free.set(w, residual_capacity[dfs]);
886            }
887            if (w==tF) {
888              __augment=true;
889              _augment=true;
890              break;
891            }
892             
893          } else {
894            F.erase(/*typename MG::OutEdgeIt*/(dfs));
895          }
896        }
897      }
898
899      if (__augment) {
900        typename MG::Node n=tF;
901        Num augment_value=free[tF];
902        while (F.valid(pred[n])) {
903          typename MG::Edge e=pred[n];
904          res_graph.augment(original_edge[e], augment_value);
905          n=F.tail(e);
906          if (residual_capacity[e]==augment_value)
907            F.erase(e);
908          else
909            residual_capacity.set(e, residual_capacity[e]-augment_value);
910        }
911      }
912       
913    }
914           
915    return _augment;
916  }
917
918
919
920
921
922
923  template <typename Graph, typename Num, typename CapMap, typename FlowMap>
924  bool MaxFlow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow2()
925  {
926    bool _augment=false;
927
928    ResGW res_graph(*g, *capacity, *flow);
929     
930    //ReachedMap level(res_graph);
931    FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
932    BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
933
934    bfs.pushAndSetReached(s);
935    DistanceMap<ResGW> dist(res_graph);
936    while ( !bfs.finished() ) {
937      ResGWOutEdgeIt e=bfs;
938      if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
939        dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
940      }
941      ++bfs;
942    } //computing distances from s in the residual graph
943
944      //Subgraph containing the edges on some shortest paths
945    ConstMap<typename ResGW::Node, bool> true_map(true);
946    typedef SubGraphWrapper<ResGW, ConstMap<typename ResGW::Node, bool>,
947      DistanceMap<ResGW> > FilterResGW;
948    FilterResGW filter_res_graph(res_graph, true_map, dist);
949
950    //Subgraph, which is able to delete edges which are already
951    //met by the dfs
952    typename FilterResGW::template NodeMap<typename FilterResGW::OutEdgeIt>
953      first_out_edges(filter_res_graph);
954    typename FilterResGW::NodeIt v;
955    for(filter_res_graph.first(v); filter_res_graph.valid(v);
956        filter_res_graph.next(v))
957      {
958        typename FilterResGW::OutEdgeIt e;
959        filter_res_graph.first(e, v);
960        first_out_edges.set(v, e);
961      }
962    typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
963      template NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
964    ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
965
966    bool __augment=true;
967
968    while (__augment) {
969
970      __augment=false;
971      //computing blocking flow with dfs
972      DfsIterator< ErasingResGW,
973        typename ErasingResGW::template NodeMap<bool> >
974        dfs(erasing_res_graph);
975      typename ErasingResGW::
976        template NodeMap<typename ErasingResGW::OutEdgeIt>
977        pred(erasing_res_graph);
978      pred.set(s, INVALID);
979      //invalid iterators for sources
980
981      typename ErasingResGW::template NodeMap<Num>
982        free1(erasing_res_graph);
983
984      dfs.pushAndSetReached(
985                            typename ErasingResGW::Node(
986                                                        typename FilterResGW::Node(
987                                                                                   typename ResGW::Node(s)
988                                                                                   )
989                                                        )
990                            );
991      while (!dfs.finished()) {
992        ++dfs;
993        if (erasing_res_graph.valid(
994                                    typename ErasingResGW::OutEdgeIt(dfs)))
995          {
996            if (dfs.isBNodeNewlyReached()) {
997         
998              typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs);
999              typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs);
1000
1001              pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs));
1002              if (erasing_res_graph.valid(pred[v])) {
1003                free1.set(w, std::min(free1[v], res_graph.resCap(
1004                                                                 typename ErasingResGW::OutEdgeIt(dfs))));
1005              } else {
1006                free1.set(w, res_graph.resCap(
1007                                              typename ErasingResGW::OutEdgeIt(dfs)));
1008              }
1009             
1010              if (w==t) {
1011                __augment=true;
1012                _augment=true;
1013                break;
1014              }
1015            } else {
1016              erasing_res_graph.erase(dfs);
1017            }
1018          }
1019      }
1020
1021      if (__augment) {
1022        typename ErasingResGW::Node n=typename FilterResGW::Node(typename ResGW::Node(t));
1023        //        typename ResGW::NodeMap<Num> a(res_graph);
1024        //        typename ResGW::Node b;
1025        //        Num j=a[b];
1026        //        typename FilterResGW::NodeMap<Num> a1(filter_res_graph);
1027        //        typename FilterResGW::Node b1;
1028        //        Num j1=a1[b1];
1029        //        typename ErasingResGW::NodeMap<Num> a2(erasing_res_graph);
1030        //        typename ErasingResGW::Node b2;
1031        //        Num j2=a2[b2];
1032        Num augment_value=free1[n];
1033        while (erasing_res_graph.valid(pred[n])) {
1034          typename ErasingResGW::OutEdgeIt e=pred[n];
1035          res_graph.augment(e, augment_value);
1036          n=erasing_res_graph.tail(e);
1037          if (res_graph.resCap(e)==0)
1038            erasing_res_graph.erase(e);
1039        }
1040      }
1041     
1042    } //while (__augment)
1043           
1044    return _augment;
1045  }
1046
1047
1048
1049
1050} //namespace hugo
1051
1052#endif //HUGO_MAX_FLOW_H
1053
1054
1055
1056
Note: See TracBrowser for help on using the repository browser.