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