lemon/preflow.h
author deba
Wed, 01 Mar 2006 10:25:30 +0000
changeset 1991 d7442141d9ef
parent 1953 d4f411003580
child 1993 2115143eceea
permissions -rw-r--r--
The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.

The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.

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