src/work/marci/augmenting_flow.h
author alpar
Mon, 06 Sep 2004 09:21:35 +0000
changeset 808 9cabbdd73375
parent 775 e46a1f0623a0
child 854 baf0b6e40211
permissions -rw-r--r--
Bug: This file must be updated.
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