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