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