lemon/preflow.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2033 7bf1f64962c2
child 2330 9dccb1abc721
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

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