src/work/jacint/max_save.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000 (2004-09-08)
changeset 822 88226d9fe821
child 921 818510fa3d99
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

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