COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/hugo/max_flow.h @ 759:2d2d41010cb9

Last change on this file since 759:2d2d41010cb9 was 758:49b1a30c4dc4, checked in by Alpar Juttner, 20 years ago

New Doxygen module for path/flow algs.

File size: 24.1 KB
Line 
1// -*- C++ -*-
2#ifndef HUGO_MAX_FLOW_H
3#define HUGO_MAX_FLOW_H
4
5#include <vector>
6#include <queue>
7
8#include <hugo/graph_wrapper.h>
9#include <hugo/invalid.h>
10#include <hugo/maps.h>
11
12/// \file
13/// \ingroup flowalgs
14
15namespace hugo {
16
17  /// \addtogroup flowalgs
18  /// @{                                                   
19
20  ///Maximum flow algorithms class.
21
22  ///This class provides various algorithms for finding a flow of
23  ///maximum value in a directed graph. The \e source node, the \e
24  ///target node, the \e capacity of the edges and the \e starting \e
25  ///flow value of the edges should be passed to the algorithm through the
26  ///constructor. It is possible to change these quantities using the
27  ///functions \ref setSource, \ref setTarget, \ref setCap and
28  ///\ref setFlow. Before any subsequent runs of any algorithm of
29  ///the class \ref setFlow should be called.
30  ///
31  ///After running an algorithm of the class, the actual flow value
32  ///can be obtained by calling \ref flowValue(). The minimum
33  ///value cut can be written into a \c node map of \c bools by
34  ///calling \ref minCut. (\ref minMinCut and \ref maxMinCut writes
35  ///the inclusionwise minimum and maximum of the minimum value
36  ///cuts, resp.)
37  ///
38  ///\param Graph The directed graph type the algorithm runs on.
39  ///\param Num The number type of the capacities and the flow values.
40  ///\param CapMap The capacity map type.
41  ///\param FlowMap The flow map type.
42  ///
43  ///\author Marton Makai, Jacint Szabo
44  template <typename Graph, typename Num,
45            typename CapMap=typename Graph::template EdgeMap<Num>,
46            typename FlowMap=typename Graph::template EdgeMap<Num> >
47  class MaxFlow {
48  protected:
49    typedef typename Graph::Node Node;
50    typedef typename Graph::NodeIt NodeIt;
51    typedef typename Graph::EdgeIt EdgeIt;
52    typedef typename Graph::OutEdgeIt OutEdgeIt;
53    typedef typename Graph::InEdgeIt InEdgeIt;
54
55    typedef typename std::vector<Node> VecFirst;
56    typedef typename Graph::template NodeMap<Node> NNMap;
57    typedef typename std::vector<Node> VecNode;
58
59    const Graph* g;
60    Node s;
61    Node t;
62    const CapMap* capacity;
63    FlowMap* flow;
64    int n;      //the number of nodes of G
65    typedef ResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;   
66    //typedef ExpResGraphWrapper<const Graph, Num, CapMap, FlowMap> ResGW;
67    typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
68    typedef typename ResGW::Edge ResGWEdge;
69    typedef typename Graph::template NodeMap<int> ReachedMap;
70
71
72    //level works as a bool map in augmenting path algorithms and is
73    //used by bfs for storing reached information.  In preflow, it
74    //shows the levels of nodes.     
75    ReachedMap level;
76
77    //excess is needed only in preflow
78    typename Graph::template NodeMap<Num> excess;
79
80    // constants used for heuristics
81    static const int H0=20;
82    static const int H1=1;
83
84  public:
85
86    ///Indicates the property of the starting flow.
87
88    ///Indicates the property of the starting flow. The meanings are as follows:
89    ///- \c ZERO_FLOW: constant zero flow
90    ///- \c GEN_FLOW: any flow, i.e. the sum of the in-flows equals to
91    ///the sum of the out-flows in every node except the \e source and
92    ///the \e target.
93    ///- \c PRE_FLOW: any preflow, i.e. the sum of the in-flows is at
94    ///least the sum of the out-flows in every node except the \e source.
95    ///- \c NO_FLOW: indicates an unspecified edge map. \ref flow will be
96    ///set to the constant zero flow in the beginning of the algorithm in this case.
97    enum FlowEnum{
98      ZERO_FLOW,
99      GEN_FLOW,
100      PRE_FLOW,
101      NO_FLOW
102    };
103
104    enum StatusEnum {
105      AFTER_NOTHING,
106      AFTER_AUGMENTING,
107      AFTER_FAST_AUGMENTING,
108      AFTER_PRE_FLOW_PHASE_1,     
109      AFTER_PRE_FLOW_PHASE_2
110    };
111
112    /// Do not needle this flag only if necessary.
113    StatusEnum status;
114
115//     int number_of_augmentations;
116
117
118//     template<typename IntMap>
119//     class TrickyReachedMap {
120//     protected:
121//       IntMap* map;
122//       int* number_of_augmentations;
123//     public:
124//       TrickyReachedMap(IntMap& _map, int& _number_of_augmentations) :
125//      map(&_map), number_of_augmentations(&_number_of_augmentations) { }
126//       void set(const Node& n, bool b) {
127//      if (b)
128//        map->set(n, *number_of_augmentations);
129//      else
130//        map->set(n, *number_of_augmentations-1);
131//       }
132//       bool operator[](const Node& n) const {
133//      return (*map)[n]==*number_of_augmentations;
134//       }
135//     };
136   
137    ///Constructor
138
139    ///\todo Document, please.
140    ///
141    MaxFlow(const Graph& _G, Node _s, Node _t,
142            const CapMap& _capacity, FlowMap& _flow) :
143      g(&_G), s(_s), t(_t), capacity(&_capacity),
144      flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0),
145      status(AFTER_NOTHING) { }
146
147    ///Runs a maximum flow algorithm.
148
149    ///Runs a preflow algorithm, which is the fastest maximum flow
150    ///algorithm up-to-date. The default for \c fe is ZERO_FLOW.
151    ///\pre The starting flow must be
152    /// - a constant zero flow if \c fe is \c ZERO_FLOW,
153    /// - an arbitary flow if \c fe is \c GEN_FLOW,
154    /// - an arbitary preflow if \c fe is \c PRE_FLOW,
155    /// - any map if \c fe is NO_FLOW.
156    void run(FlowEnum fe=ZERO_FLOW) {
157      preflow(fe);
158    }
159
160                                                                             
161    ///Runs a preflow algorithm. 
162
163    ///Runs a preflow algorithm. The preflow algorithms provide the
164    ///fastest way to compute a maximum flow in a directed graph.
165    ///\pre The starting flow must be
166    /// - a constant zero flow if \c fe is \c ZERO_FLOW,
167    /// - an arbitary flow if \c fe is \c GEN_FLOW,
168    /// - an arbitary preflow if \c fe is \c PRE_FLOW,
169    /// - any map if \c fe is NO_FLOW.
170    ///
171    ///\todo NO_FLOW should be the default flow.
172    void preflow(FlowEnum fe) {
173      preflowPhase1(fe);
174      preflowPhase2();
175    }
176    // Heuristics:
177    //   2 phase
178    //   gap
179    //   list 'level_list' on the nodes on level i implemented by hand
180    //   stack 'active' on the active nodes on level i                                                                                   
181    //   runs heuristic 'highest label' for H1*n relabels
182    //   runs heuristic 'bound decrease' for H0*n relabels, starts with 'highest label'
183    //   Parameters H0 and H1 are initialized to 20 and 1.
184
185    ///Runs the first phase of the preflow algorithm.
186
187    ///The preflow algorithm consists of two phases, this method runs the
188    ///first phase. After the first phase the maximum flow value and a
189    ///minimum value cut can already be computed, though a maximum flow
190    ///is not yet obtained. So after calling this method \ref flowValue
191    ///and \ref actMinCut gives proper results.
192    ///\warning: \ref minCut, \ref minMinCut and \ref maxMinCut do not
193    ///give minimum value cuts unless calling \ref preflowPhase2.
194    ///\pre The starting flow must be
195    /// - a constant zero flow if \c fe is \c ZERO_FLOW,
196    /// - an arbitary flow if \c fe is \c GEN_FLOW,
197    /// - an arbitary preflow if \c fe is \c PRE_FLOW,
198    /// - any map if \c fe is NO_FLOW.
199    void preflowPhase1(FlowEnum fe)
200    {
201
202      int heur0=(int)(H0*n);  //time while running 'bound decrease'
203      int heur1=(int)(H1*n);  //time while running 'highest label'
204      int heur=heur1;         //starting time interval (#of relabels)
205      int numrelabel=0;
206
207      bool what_heur=1;
208      //It is 0 in case 'bound decrease' and 1 in case 'highest label'
209
210      bool end=false;
211      //Needed for 'bound decrease', true means no active nodes are above bound
212      //b.
213
214      int k=n-2;  //bound on the highest level under n containing a node
215      int b=k;    //bound on the highest level under n of an active node
216
217      VecFirst first(n, INVALID);
218      NNMap next(*g, INVALID); //maybe INVALID is not needed
219
220      NNMap left(*g, INVALID);
221      NNMap right(*g, INVALID);
222      VecNode level_list(n,INVALID);
223      //List of the nodes in level i<n, set to n.
224
225      preflowPreproc(fe, next, first, level_list, left, right);
226      //End of preprocessing
227
228      //Push/relabel on the highest level active nodes.
229      while ( true ) {
230        if ( b == 0 ) {
231          if ( !what_heur && !end && k > 0 ) {
232            b=k;
233            end=true;
234          } else break;
235        }
236
237        if ( !g->valid(first[b]) ) --b;
238        else {
239          end=false;
240          Node w=first[b];
241          first[b]=next[w];
242          int newlevel=push(w, next, first);
243          if ( excess[w] > 0 ) relabel(w, newlevel, next, first, level_list,
244                                       left, right, b, k, what_heur);
245
246          ++numrelabel;
247          if ( numrelabel >= heur ) {
248            numrelabel=0;
249            if ( what_heur ) {
250              what_heur=0;
251              heur=heur0;
252              end=false;
253            } else {
254              what_heur=1;
255              heur=heur1;
256              b=k;
257            }
258          }
259        }
260      }
261
262      status=AFTER_PRE_FLOW_PHASE_1;
263    }
264
265
266    ///Runs the second phase of the preflow algorithm.
267
268    ///The preflow algorithm consists of two phases, this method runs
269    ///the second phase. After calling \ref preflowPhase1 and then
270    ///\ref preflowPhase2 the methods \ref flowValue, \ref minCut,
271    ///\ref minMinCut and \ref maxMinCut give proper results.
272    ///\pre \ref preflowPhase1 must be called before.
273    void preflowPhase2()
274    {
275
276      int k=n-2;  //bound on the highest level under n containing a node
277      int b=k;    //bound on the highest level under n of an active node
278
279   
280      VecFirst first(n, INVALID);
281      NNMap next(*g, INVALID); //maybe INVALID is not needed
282      level.set(s,0);
283      std::queue<Node> bfs_queue;
284      bfs_queue.push(s);
285
286      while (!bfs_queue.empty()) {
287
288        Node v=bfs_queue.front();
289        bfs_queue.pop();
290        int l=level[v]+1;
291
292        InEdgeIt e;
293        for(g->first(e,v); g->valid(e); g->next(e)) {
294          if ( (*capacity)[e] <= (*flow)[e] ) continue;
295          Node u=g->tail(e);
296          if ( level[u] >= n ) {
297            bfs_queue.push(u);
298            level.set(u, l);
299            if ( excess[u] > 0 ) {
300              next.set(u,first[l]);
301              first[l]=u;
302            }
303          }
304        }
305
306        OutEdgeIt f;
307        for(g->first(f,v); g->valid(f); g->next(f)) {
308          if ( 0 >= (*flow)[f] ) continue;
309          Node u=g->head(f);
310          if ( level[u] >= n ) {
311            bfs_queue.push(u);
312            level.set(u, l);
313            if ( excess[u] > 0 ) {
314              next.set(u,first[l]);
315              first[l]=u;
316            }
317          }
318        }
319      }
320      b=n-2;
321
322      while ( true ) {
323
324        if ( b == 0 ) break;
325
326        if ( !g->valid(first[b]) ) --b;
327        else {
328
329          Node w=first[b];
330          first[b]=next[w];
331          int newlevel=push(w,next, first/*active*/);
332
333          //relabel
334          if ( excess[w] > 0 ) {
335            level.set(w,++newlevel);
336            next.set(w,first[newlevel]);
337            first[newlevel]=w;
338            b=newlevel;
339          }
340        }
341      } // while(true)
342
343      status=AFTER_PRE_FLOW_PHASE_2;
344    }
345
346
347    /// Returns the maximum value of a flow.
348
349    /// Returns the maximum value of a flow, by counting the
350    /// over-flow of the target node \ref t.
351    /// It can be called already after running \ref preflowPhase1.
352    Num flowValue() const {
353      Num a=0;
354      for(InEdgeIt e(*g,t);g->valid(e);g->next(e)) a+=(*flow)[e];
355      for(OutEdgeIt e(*g,t);g->valid(e);g->next(e)) a-=(*flow)[e];
356      return a;
357      //marci figyu: excess[t] epp ezt adja preflow 1. fazisa utan   
358    }
359
360
361    ///Returns a minimum value cut after calling \ref preflowPhase1.
362
363    ///After the first phase of the preflow algorithm the maximum flow
364    ///value and a minimum value cut can already be computed. This
365    ///method can be called after running \ref preflowPhase1 for
366    ///obtaining a minimum value cut.
367    /// \warning Gives proper result only right after calling \ref
368    /// preflowPhase1.
369    /// \todo We have to make some status variable which shows the
370    /// actual state
371    /// of the class. This enables us to determine which methods are valid
372    /// for MinCut computation
373    template<typename _CutMap>
374    void actMinCut(_CutMap& M) const {
375      NodeIt v;
376      switch (status) {
377      case AFTER_PRE_FLOW_PHASE_1:
378        for(g->first(v); g->valid(v); g->next(v)) {
379          if (level[v] < n) {
380            M.set(v, false);
381          } else {
382            M.set(v, true);
383          }
384        }
385        break;
386      case AFTER_PRE_FLOW_PHASE_2:
387      case AFTER_NOTHING:
388      case AFTER_AUGMENTING:
389      case AFTER_FAST_AUGMENTING:
390        minMinCut(M);
391        break;
392      }
393    }
394
395    ///Returns the inclusionwise minimum of the minimum value cuts.
396
397    ///Sets \c M to the characteristic vector of the minimum value cut
398    ///which is inclusionwise minimum. It is computed by processing
399    ///a bfs from the source node \c s in the residual graph.
400    ///\pre M should be a node map of bools initialized to false.
401    ///\pre \c flow must be a maximum flow.
402    template<typename _CutMap>
403    void minMinCut(_CutMap& M) const {
404      std::queue<Node> queue;
405
406      M.set(s,true);
407      queue.push(s);
408
409      while (!queue.empty()) {
410        Node w=queue.front();
411        queue.pop();
412
413        OutEdgeIt e;
414        for(g->first(e,w) ; g->valid(e); g->next(e)) {
415          Node v=g->head(e);
416          if (!M[v] && (*flow)[e] < (*capacity)[e] ) {
417            queue.push(v);
418            M.set(v, true);
419          }
420        }
421
422        InEdgeIt f;
423        for(g->first(f,w) ; g->valid(f); g->next(f)) {
424          Node v=g->tail(f);
425          if (!M[v] && (*flow)[f] > 0 ) {
426            queue.push(v);
427            M.set(v, true);
428          }
429        }
430      }
431    }
432
433    ///Returns the inclusionwise maximum of the minimum value cuts.
434
435    ///Sets \c M to the characteristic vector of the minimum value cut
436    ///which is inclusionwise maximum. It is computed by processing a
437    ///backward bfs from the target node \c t in the residual graph.
438    ///\pre M should be a node map of bools initialized to false.
439    ///\pre \c flow must be a maximum flow.
440    template<typename _CutMap>
441    void maxMinCut(_CutMap& M) const {
442
443      NodeIt v;
444      for(g->first(v) ; g->valid(v); g->next(v)) {
445        M.set(v, true);
446      }
447
448      std::queue<Node> queue;
449
450      M.set(t,false);
451      queue.push(t);
452
453      while (!queue.empty()) {
454        Node w=queue.front();
455        queue.pop();
456
457        InEdgeIt e;
458        for(g->first(e,w) ; g->valid(e); g->next(e)) {
459          Node v=g->tail(e);
460          if (M[v] && (*flow)[e] < (*capacity)[e] ) {
461            queue.push(v);
462            M.set(v, false);
463          }
464        }
465
466        OutEdgeIt f;
467        for(g->first(f,w) ; g->valid(f); g->next(f)) {
468          Node v=g->head(f);
469          if (M[v] && (*flow)[f] > 0 ) {
470            queue.push(v);
471            M.set(v, false);
472          }
473        }
474      }
475    }
476
477    ///Returns a minimum value cut.
478
479    ///Sets \c M to the characteristic vector of a minimum value cut.
480    ///\pre M should be a node map of bools initialized to false.
481    ///\pre \c flow must be a maximum flow.   
482    template<typename CutMap>
483    void minCut(CutMap& M) const { minMinCut(M); }
484
485    ///Sets the source node to \c _s.
486
487    ///Sets the source node to \c _s.
488    ///
489    void setSource(Node _s) { s=_s; status=AFTER_NOTHING; }
490
491    ///Sets the target node to \c _t.
492
493    ///Sets the target node to \c _t.
494    ///
495    void setTarget(Node _t) { t=_t; status=AFTER_NOTHING; }
496
497    /// Sets the edge map of the capacities to _cap.
498
499    /// Sets the edge map of the capacities to _cap.
500    ///
501    void setCap(const CapMap& _cap)
502    { capacity=&_cap; status=AFTER_NOTHING; }
503
504    /// Sets the edge map of the flows to _flow.
505
506    /// Sets the edge map of the flows to _flow.
507    ///
508    void setFlow(FlowMap& _flow) { flow=&_flow; status=AFTER_NOTHING; }
509
510
511  private:
512
513    int push(Node w, NNMap& next, VecFirst& first) {
514
515      int lev=level[w];
516      Num exc=excess[w];
517      int newlevel=n;       //bound on the next level of w
518
519      OutEdgeIt e;
520      for(g->first(e,w); g->valid(e); g->next(e)) {
521
522        if ( (*flow)[e] >= (*capacity)[e] ) continue;
523        Node v=g->head(e);
524
525        if( lev > level[v] ) { //Push is allowed now
526
527          if ( excess[v]<=0 && v!=t && v!=s ) {
528            next.set(v,first[level[v]]);
529            first[level[v]]=v;
530          }
531
532          Num cap=(*capacity)[e];
533          Num flo=(*flow)[e];
534          Num remcap=cap-flo;
535
536          if ( remcap >= exc ) { //A nonsaturating push.
537
538            flow->set(e, flo+exc);
539            excess.set(v, excess[v]+exc);
540            exc=0;
541            break;
542
543          } else { //A saturating push.
544            flow->set(e, cap);
545            excess.set(v, excess[v]+remcap);
546            exc-=remcap;
547          }
548        } else if ( newlevel > level[v] ) newlevel = level[v];
549      } //for out edges wv
550
551      if ( exc > 0 ) {
552        InEdgeIt e;
553        for(g->first(e,w); g->valid(e); g->next(e)) {
554
555          if( (*flow)[e] <= 0 ) continue;
556          Node v=g->tail(e);
557
558          if( lev > level[v] ) { //Push is allowed now
559
560            if ( excess[v]<=0 && v!=t && v!=s ) {
561              next.set(v,first[level[v]]);
562              first[level[v]]=v;
563            }
564
565            Num flo=(*flow)[e];
566
567            if ( flo >= exc ) { //A nonsaturating push.
568
569              flow->set(e, flo-exc);
570              excess.set(v, excess[v]+exc);
571              exc=0;
572              break;
573            } else {  //A saturating push.
574
575              excess.set(v, excess[v]+flo);
576              exc-=flo;
577              flow->set(e,0);
578            }
579          } else if ( newlevel > level[v] ) newlevel = level[v];
580        } //for in edges vw
581
582      } // if w still has excess after the out edge for cycle
583
584      excess.set(w, exc);
585
586      return newlevel;
587    }
588
589
590
591    void preflowPreproc(FlowEnum fe, NNMap& next, VecFirst& first,
592                        VecNode& level_list, NNMap& left, NNMap& right)
593    {
594      switch (fe) { //setting excess
595        case NO_FLOW:
596        {
597          EdgeIt e;
598          for(g->first(e); g->valid(e); g->next(e)) flow->set(e,0);
599         
600          NodeIt v;
601          for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
602          break;
603        }
604        case ZERO_FLOW:
605        {
606          NodeIt v;
607          for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
608          break;
609        }
610        case GEN_FLOW:
611        {
612          NodeIt v;
613          for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
614
615          Num exc=0;
616          InEdgeIt e;
617          for(g->first(e,t); g->valid(e); g->next(e)) exc+=(*flow)[e];
618          OutEdgeIt f;
619          for(g->first(f,t); g->valid(f); g->next(f)) exc-=(*flow)[f];
620          excess.set(t,exc);
621          break;
622        }
623        default: break;
624      }
625
626      NodeIt v;
627      for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
628      //setting each node to level n
629     
630      std::queue<Node> bfs_queue;
631
632
633      switch (fe) {
634      case NO_FLOW:   //flow is already set to const zero
635      case ZERO_FLOW:
636        {
637          //Reverse_bfs from t, to find the starting level.
638          level.set(t,0);
639          bfs_queue.push(t);
640
641          while (!bfs_queue.empty()) {
642
643            Node v=bfs_queue.front();
644            bfs_queue.pop();
645            int l=level[v]+1;
646
647            InEdgeIt e;
648            for(g->first(e,v); g->valid(e); g->next(e)) {
649              Node w=g->tail(e);
650              if ( level[w] == n && w != s ) {
651                bfs_queue.push(w);
652                Node z=level_list[l];
653                if ( g->valid(z) ) left.set(z,w);
654                right.set(w,z);
655                level_list[l]=w;
656                level.set(w, l);
657              }
658            }
659          }
660
661          //the starting flow
662          OutEdgeIt e;
663          for(g->first(e,s); g->valid(e); g->next(e))
664            {
665              Num c=(*capacity)[e];
666              if ( c <= 0 ) continue;
667              Node w=g->head(e);
668              if ( level[w] < n ) {
669                if ( excess[w] <= 0 && w!=t ) //putting into the stack
670                  {
671                    next.set(w,first[level[w]]);
672                    first[level[w]]=w;
673                  }
674                flow->set(e, c);
675                excess.set(w, excess[w]+c);
676              }
677            }
678          break;
679        }
680
681      case GEN_FLOW:
682        {
683          //Reverse_bfs from t in the residual graph,
684          //to find the starting level.
685          level.set(t,0);
686          bfs_queue.push(t);
687
688          while (!bfs_queue.empty()) {
689
690            Node v=bfs_queue.front();
691            bfs_queue.pop();
692            int l=level[v]+1;
693
694            InEdgeIt e;
695            for(g->first(e,v); g->valid(e); g->next(e)) {
696              if ( (*capacity)[e] <= (*flow)[e] ) continue;
697              Node w=g->tail(e);
698              if ( level[w] == n && w != s ) {
699                bfs_queue.push(w);
700                Node z=level_list[l];
701                if ( g->valid(z) ) left.set(z,w);
702                right.set(w,z);
703                level_list[l]=w;
704                level.set(w, l);
705              }
706            }
707
708            OutEdgeIt f;
709            for(g->first(f,v); g->valid(f); g->next(f)) {
710              if ( 0 >= (*flow)[f] ) continue;
711              Node w=g->head(f);
712              if ( level[w] == n && w != s ) {
713                bfs_queue.push(w);
714                Node z=level_list[l];
715                if ( g->valid(z) ) left.set(z,w);
716                right.set(w,z);
717                level_list[l]=w;
718                level.set(w, l);
719              }
720            }
721          }
722
723          //the starting flow
724          OutEdgeIt e;
725          for(g->first(e,s); g->valid(e); g->next(e))
726            {
727              Num rem=(*capacity)[e]-(*flow)[e];
728              if ( rem <= 0 ) continue;
729              Node w=g->head(e);
730              if ( level[w] < n ) {
731                if ( excess[w] <= 0 && w!=t ) //putting into the stack
732                  {
733                    next.set(w,first[level[w]]);
734                    first[level[w]]=w;
735                  }   
736                flow->set(e, (*capacity)[e]);
737                excess.set(w, excess[w]+rem);
738              }
739            }
740
741          InEdgeIt f;
742          for(g->first(f,s); g->valid(f); g->next(f))
743            {
744              if ( (*flow)[f] <= 0 ) continue;
745              Node w=g->tail(f);
746              if ( level[w] < n ) {
747                if ( excess[w] <= 0 && w!=t )
748                  {
749                    next.set(w,first[level[w]]);
750                    first[level[w]]=w;
751                  } 
752                excess.set(w, excess[w]+(*flow)[f]);
753                flow->set(f, 0);
754              }
755            }
756          break;
757        } //case GEN_FLOW
758   
759      case PRE_FLOW:
760        {
761          //Reverse_bfs from t in the residual graph,
762          //to find the starting level.
763          level.set(t,0);
764          bfs_queue.push(t);
765
766          while (!bfs_queue.empty()) {
767
768            Node v=bfs_queue.front();
769            bfs_queue.pop();
770            int l=level[v]+1;
771
772            InEdgeIt e;
773            for(g->first(e,v); g->valid(e); g->next(e)) {
774              if ( (*capacity)[e] <= (*flow)[e] ) continue;
775              Node w=g->tail(e);
776              if ( level[w] == n && w != s ) {
777                bfs_queue.push(w);
778                Node z=level_list[l];
779                if ( g->valid(z) ) left.set(z,w);
780                right.set(w,z);
781                level_list[l]=w;
782                level.set(w, l);
783              }
784            }
785
786            OutEdgeIt f;
787            for(g->first(f,v); g->valid(f); g->next(f)) {
788              if ( 0 >= (*flow)[f] ) continue;
789              Node w=g->head(f);
790              if ( level[w] == n && w != s ) {
791                bfs_queue.push(w);
792                Node z=level_list[l];
793                if ( g->valid(z) ) left.set(z,w);
794                right.set(w,z);
795                level_list[l]=w;
796                level.set(w, l);
797              }
798            }
799          }
800
801
802          //the starting flow
803          OutEdgeIt e;
804          for(g->first(e,s); g->valid(e); g->next(e))
805            {
806              Num rem=(*capacity)[e]-(*flow)[e];
807              if ( rem <= 0 ) continue;
808              Node w=g->head(e);
809              if ( level[w] < n ) {
810                flow->set(e, (*capacity)[e]);
811                excess.set(w, excess[w]+rem);
812              }
813            }
814
815          InEdgeIt f;
816          for(g->first(f,s); g->valid(f); g->next(f))
817            {
818              if ( (*flow)[f] <= 0 ) continue;
819              Node w=g->tail(f);
820              if ( level[w] < n ) {
821                excess.set(w, excess[w]+(*flow)[f]);
822                flow->set(f, 0);
823              }
824            }
825         
826          NodeIt w; //computing the excess
827          for(g->first(w); g->valid(w); g->next(w)) {
828            Num exc=0;
829
830            InEdgeIt e;
831            for(g->first(e,w); g->valid(e); g->next(e)) exc+=(*flow)[e];
832            OutEdgeIt f;
833            for(g->first(f,w); g->valid(f); g->next(f)) exc-=(*flow)[f];
834
835            excess.set(w,exc);
836
837            //putting the active nodes into the stack
838            int lev=level[w];
839            if ( exc > 0 && lev < n && w != t )
840              {
841                next.set(w,first[lev]);
842                first[lev]=w;
843              }
844          }
845          break;
846        } //case PRE_FLOW
847      }
848    } //preflowPreproc
849
850
851    void relabel(Node w, int newlevel, NNMap& next, VecFirst& first,
852                 VecNode& level_list, NNMap& left,
853                 NNMap& right, int& b, int& k, bool what_heur )
854    {
855
856      Num lev=level[w];
857
858      Node right_n=right[w];
859      Node left_n=left[w];
860
861      //unlacing starts
862      if ( g->valid(right_n) ) {
863        if ( g->valid(left_n) ) {
864          right.set(left_n, right_n);
865          left.set(right_n, left_n);
866        } else {
867          level_list[lev]=right_n;
868          left.set(right_n, INVALID);
869        }
870      } else {
871        if ( g->valid(left_n) ) {
872          right.set(left_n, INVALID);
873        } else {
874          level_list[lev]=INVALID;
875        }
876      }
877      //unlacing ends
878
879      if ( !g->valid(level_list[lev]) ) {
880
881        //gapping starts
882        for (int i=lev; i!=k ; ) {
883          Node v=level_list[++i];
884          while ( g->valid(v) ) {
885            level.set(v,n);
886            v=right[v];
887          }
888          level_list[i]=INVALID;
889          if ( !what_heur ) first[i]=INVALID;
890        }
891
892        level.set(w,n);
893        b=lev-1;
894        k=b;
895        //gapping ends
896
897      } else {
898
899        if ( newlevel == n ) level.set(w,n);
900        else {
901          level.set(w,++newlevel);
902          next.set(w,first[newlevel]);
903          first[newlevel]=w;
904          if ( what_heur ) b=newlevel;
905          if ( k < newlevel ) ++k;      //now k=newlevel
906          Node z=level_list[newlevel];
907          if ( g->valid(z) ) left.set(z,w);
908          right.set(w,z);
909          left.set(w,INVALID);
910          level_list[newlevel]=w;
911        }
912      }
913    } //relabel
914
915    void printexcess() {////
916      std::cout << "Excesses:" <<std::endl;
917
918      NodeIt v;
919      for(g->first(v); g->valid(v); g->next(v)) {
920        std::cout << 1+(g->id(v)) << ":" << excess[v]<<std::endl;
921      }
922    }
923
924 void printlevel() {////
925      std::cout << "Levels:" <<std::endl;
926
927      NodeIt v;
928      for(g->first(v); g->valid(v); g->next(v)) {
929        std::cout << 1+(g->id(v)) << ":" << level[v]<<std::endl;
930      }
931    }
932
933void printactive() {////
934      std::cout << "Levels:" <<std::endl;
935
936      NodeIt v;
937      for(g->first(v); g->valid(v); g->next(v)) {
938        std::cout << 1+(g->id(v)) << ":" << level[v]<<std::endl;
939      }
940    }
941
942
943  };  //class MaxFlow
944} //namespace hugo
945
946#endif //HUGO_MAX_FLOW_H
947
948
949
950
Note: See TracBrowser for help on using the repository browser.