lemon/edmonds_karp.h
author deba
Thu, 27 Dec 2007 13:40:16 +0000
changeset 2547 f393a8162688
parent 2522 616c019215c4
child 2553 bfced05fa852
permissions -rw-r--r--
Renaming state_enum to State
Removing "Type" suffix from typedefs
Moving implementation into the class definition
deba@2034
     1
/* -*- C++ -*-
deba@2034
     2
 *
deba@2034
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2034
     4
 *
alpar@2391
     5
 * Copyright (C) 2003-2007
deba@2034
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2034
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2034
     8
 *
deba@2034
     9
 * Permission to use, modify and distribute this software is granted
deba@2034
    10
 * provided that this copyright notice appears in all copies. For
deba@2034
    11
 * precise terms see the accompanying LICENSE file.
deba@2034
    12
 *
deba@2034
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2034
    14
 * express or implied, and with no claim as to its suitability for any
deba@2034
    15
 * purpose.
deba@2034
    16
 *
deba@2034
    17
 */
deba@2034
    18
deba@2034
    19
#ifndef LEMON_EDMONDS_KARP_H
deba@2034
    20
#define LEMON_EDMONDS_KARP_H
deba@2034
    21
deba@2034
    22
/// \file
deba@2376
    23
/// \ingroup max_flow
deba@2034
    24
/// \brief Implementation of the Edmonds-Karp algorithm.
deba@2034
    25
deba@2034
    26
#include <lemon/tolerance.h>
deba@2514
    27
#include <vector>
deba@2034
    28
deba@2034
    29
namespace lemon {
deba@2034
    30
deba@2514
    31
  /// \brief Default traits class of EdmondsKarp class.
deba@2514
    32
  ///
deba@2514
    33
  /// Default traits class of EdmondsKarp class.
deba@2514
    34
  /// \param _Graph Graph type.
deba@2514
    35
  /// \param _CapacityMap Type of capacity map.
deba@2514
    36
  template <typename _Graph, typename _CapacityMap>
deba@2514
    37
  struct EdmondsKarpDefaultTraits {
deba@2514
    38
deba@2514
    39
    /// \brief The graph type the algorithm runs on. 
deba@2514
    40
    typedef _Graph Graph;
deba@2514
    41
deba@2514
    42
    /// \brief The type of the map that stores the edge capacities.
deba@2514
    43
    ///
deba@2514
    44
    /// The type of the map that stores the edge capacities.
deba@2514
    45
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
deba@2514
    46
    typedef _CapacityMap CapacityMap;
deba@2514
    47
deba@2514
    48
    /// \brief The type of the length of the edges.
deba@2514
    49
    typedef typename CapacityMap::Value Value;
deba@2514
    50
deba@2514
    51
    /// \brief The map type that stores the flow values.
deba@2514
    52
    ///
deba@2514
    53
    /// The map type that stores the flow values. 
deba@2514
    54
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
deba@2514
    55
    typedef typename Graph::template EdgeMap<Value> FlowMap;
deba@2514
    56
deba@2514
    57
    /// \brief Instantiates a FlowMap.
deba@2514
    58
    ///
deba@2514
    59
    /// This function instantiates a \ref FlowMap. 
deba@2514
    60
    /// \param graph The graph, to which we would like to define the flow map.
deba@2514
    61
    static FlowMap* createFlowMap(const Graph& graph) {
deba@2514
    62
      return new FlowMap(graph);
deba@2514
    63
    }
deba@2514
    64
deba@2514
    65
    /// \brief The tolerance used by the algorithm
deba@2514
    66
    ///
deba@2514
    67
    /// The tolerance used by the algorithm to handle inexact computation.
deba@2514
    68
    typedef Tolerance<Value> Tolerance;
deba@2514
    69
deba@2514
    70
  };
deba@2514
    71
deba@2376
    72
  /// \ingroup max_flow
deba@2514
    73
  ///
deba@2034
    74
  /// \brief Edmonds-Karp algorithms class.
deba@2034
    75
  ///
deba@2034
    76
  /// This class provides an implementation of the \e Edmonds-Karp \e
deba@2034
    77
  /// algorithm producing a flow of maximum value in a directed
deba@2514
    78
  /// graphs. The Edmonds-Karp algorithm is slower than the Preflow
deba@2514
    79
  /// algorithm but it has an advantage of the step-by-step execution
deba@2514
    80
  /// control with feasible flow solutions. The \e source node, the \e
deba@2514
    81
  /// target node, the \e capacity of the edges and the \e starting \e
deba@2514
    82
  /// flow value of the edges should be passed to the algorithm
deba@2514
    83
  /// through the constructor.
deba@2034
    84
  ///
deba@2514
    85
  /// The time complexity of the algorithm is \f$ O(nm^2) \f$ in
deba@2059
    86
  /// worst case.  Always try the preflow algorithm instead of this if
deba@2113
    87
  /// you just want to compute the optimal flow.
deba@2034
    88
  ///
deba@2034
    89
  /// \param _Graph The directed graph type the algorithm runs on.
deba@2034
    90
  /// \param _CapacityMap The capacity map type.
deba@2514
    91
  /// \param _Traits Traits class to set various data types used by
deba@2514
    92
  /// the algorithm.  The default traits class is \ref
deba@2514
    93
  /// EdmondsKarpDefaultTraits.  See \ref EdmondsKarpDefaultTraits for the
deba@2514
    94
  /// documentation of a Edmonds-Karp traits class. 
deba@2034
    95
  ///
deba@2034
    96
  /// \author Balazs Dezso 
deba@2059
    97
#ifdef DOXYGEN
deba@2514
    98
  template <typename _Graph, typename _CapacityMap, typename _Traits>
deba@2514
    99
#else 
deba@2514
   100
  template <typename _Graph,
deba@2514
   101
	    typename _CapacityMap = typename _Graph::template EdgeMap<int>,
deba@2514
   102
            typename _Traits = EdmondsKarpDefaultTraits<_Graph, _CapacityMap> >
deba@2059
   103
#endif
deba@2034
   104
  class EdmondsKarp {
deba@2034
   105
  public:
deba@2034
   106
deba@2514
   107
    typedef _Traits Traits;
deba@2514
   108
    typedef typename Traits::Graph Graph;
deba@2514
   109
    typedef typename Traits::CapacityMap CapacityMap;
deba@2514
   110
    typedef typename Traits::Value Value; 
deba@2514
   111
deba@2514
   112
    typedef typename Traits::FlowMap FlowMap;
deba@2514
   113
    typedef typename Traits::Tolerance Tolerance;
deba@2514
   114
deba@2034
   115
    /// \brief \ref Exception for the case when the source equals the target.
deba@2034
   116
    ///
deba@2034
   117
    /// \ref Exception for the case when the source equals the target.
deba@2034
   118
    ///
deba@2034
   119
    class InvalidArgument : public lemon::LogicError {
deba@2034
   120
    public:
alpar@2151
   121
      virtual const char* what() const throw() {
deba@2034
   122
	return "lemon::EdmondsKarp::InvalidArgument";
deba@2034
   123
      }
deba@2034
   124
    };
deba@2034
   125
deba@2034
   126
deba@2034
   127
  private:
deba@2034
   128
deba@2514
   129
    GRAPH_TYPEDEFS(typename Graph);
deba@2514
   130
    typedef typename Graph::template NodeMap<Edge> PredMap;
deba@2034
   131
    
deba@2514
   132
    const Graph& _graph;
deba@2514
   133
    const CapacityMap* _capacity;
deba@2514
   134
deba@2514
   135
    Node _source, _target;
deba@2514
   136
deba@2514
   137
    FlowMap* _flow;
deba@2514
   138
    bool _local_flow;
deba@2514
   139
deba@2514
   140
    PredMap* _pred;
deba@2514
   141
    std::vector<Node> _queue;
deba@2514
   142
    
deba@2514
   143
    Tolerance _tolerance;
deba@2514
   144
    Value _flow_value;
deba@2514
   145
deba@2514
   146
    void createStructures() {
deba@2514
   147
      if (!_flow) {
deba@2514
   148
	_flow = Traits::createFlowMap(_graph);
deba@2514
   149
	_local_flow = true;
deba@2514
   150
      }
deba@2514
   151
      if (!_pred) {
deba@2514
   152
	_pred = new PredMap(_graph);
deba@2514
   153
      }
deba@2514
   154
      _queue.resize(countNodes(_graph));
deba@2514
   155
    }
deba@2514
   156
deba@2514
   157
    void destroyStructures() {
deba@2514
   158
      if (_local_flow) {
deba@2514
   159
	delete _flow;
deba@2514
   160
      }
deba@2514
   161
      if (_pred) {
deba@2514
   162
	delete _pred;
deba@2514
   163
      }
deba@2514
   164
    }
deba@2034
   165
    
deba@2034
   166
  public:
deba@2034
   167
deba@2514
   168
    ///\name Named template parameters
deba@2514
   169
deba@2514
   170
    ///@{
deba@2514
   171
deba@2514
   172
    template <typename _FlowMap>
deba@2514
   173
    struct DefFlowMapTraits : public Traits {
deba@2514
   174
      typedef _FlowMap FlowMap;
deba@2514
   175
      static FlowMap *createFlowMap(const Graph&) {
deba@2514
   176
	throw UninitializedParameter();
deba@2514
   177
      }
deba@2514
   178
    };
deba@2514
   179
deba@2514
   180
    /// \brief \ref named-templ-param "Named parameter" for setting
deba@2514
   181
    /// FlowMap type
deba@2514
   182
    ///
deba@2514
   183
    /// \ref named-templ-param "Named parameter" for setting FlowMap
deba@2514
   184
    /// type
deba@2514
   185
    template <typename _FlowMap>
deba@2514
   186
    struct DefFlowMap 
deba@2514
   187
      : public EdmondsKarp<Graph, CapacityMap, DefFlowMapTraits<_FlowMap> > {
deba@2514
   188
      typedef EdmondsKarp<Graph, CapacityMap, DefFlowMapTraits<_FlowMap> > 
deba@2514
   189
      Create;
deba@2514
   190
    };
deba@2514
   191
deba@2514
   192
deba@2514
   193
    /// @}
deba@2514
   194
deba@2527
   195
  protected:
deba@2527
   196
    
deba@2527
   197
    EdmondsKarp() {}
deba@2527
   198
deba@2527
   199
  public:
deba@2527
   200
deba@2034
   201
    /// \brief The constructor of the class.
deba@2034
   202
    ///
deba@2034
   203
    /// The constructor of the class. 
deba@2037
   204
    /// \param graph The directed graph the algorithm runs on. 
deba@2514
   205
    /// \param capacity The capacity of the edges. 
deba@2037
   206
    /// \param source The source node.
deba@2037
   207
    /// \param target The target node.
deba@2514
   208
    EdmondsKarp(const Graph& graph, const CapacityMap& capacity,
deba@2514
   209
		Node source, Node target)
deba@2514
   210
      : _graph(graph), _capacity(&capacity), _source(source), _target(target),
deba@2514
   211
	_flow(0), _local_flow(false), _pred(0), _tolerance(), _flow_value()
deba@2034
   212
    {
deba@2034
   213
      if (_source == _target) {
deba@2034
   214
        throw InvalidArgument();
deba@2034
   215
      }
deba@2034
   216
    }
deba@2034
   217
deba@2514
   218
    /// \brief Destrcutor.
deba@2514
   219
    ///
deba@2514
   220
    /// Destructor.
deba@2514
   221
    ~EdmondsKarp() {
deba@2514
   222
      destroyStructures();
deba@2514
   223
    }
deba@2514
   224
deba@2514
   225
    /// \brief Sets the capacity map.
deba@2514
   226
    ///
deba@2514
   227
    /// Sets the capacity map.
deba@2514
   228
    /// \return \c (*this)
deba@2514
   229
    EdmondsKarp& capacityMap(const CapacityMap& map) {
deba@2514
   230
      _capacity = &map;
deba@2514
   231
      return *this;
deba@2514
   232
    }
deba@2514
   233
deba@2514
   234
    /// \brief Sets the flow map.
deba@2514
   235
    ///
deba@2514
   236
    /// Sets the flow map.
deba@2514
   237
    /// \return \c (*this)
deba@2514
   238
    EdmondsKarp& flowMap(FlowMap& map) {
deba@2514
   239
      if (_local_flow) {
deba@2514
   240
	delete _flow;
deba@2514
   241
	_local_flow = false;
deba@2514
   242
      }
deba@2514
   243
      _flow = &map;
deba@2514
   244
      return *this;
deba@2514
   245
    }
deba@2514
   246
deba@2514
   247
    /// \brief Returns the flow map.
deba@2514
   248
    ///
deba@2514
   249
    /// \return The flow map.
deba@2514
   250
    const FlowMap& flowMap() {
deba@2514
   251
      return *_flow;
deba@2514
   252
    }
deba@2514
   253
deba@2514
   254
    /// \brief Sets the source node.
deba@2514
   255
    ///
deba@2514
   256
    /// Sets the source node.
deba@2514
   257
    /// \return \c (*this)
deba@2514
   258
    EdmondsKarp& source(const Node& node) {
deba@2514
   259
      _source = node;
deba@2514
   260
      return *this;
deba@2514
   261
    }
deba@2514
   262
deba@2514
   263
    /// \brief Sets the target node.
deba@2514
   264
    ///
deba@2514
   265
    /// Sets the target node.
deba@2514
   266
    /// \return \c (*this)
deba@2514
   267
    EdmondsKarp& target(const Node& node) {
deba@2514
   268
      _target = node;
deba@2514
   269
      return *this;
deba@2514
   270
    }
deba@2514
   271
deba@2514
   272
    /// \brief Sets the tolerance used by algorithm.
deba@2514
   273
    ///
deba@2514
   274
    /// Sets the tolerance used by algorithm.
deba@2514
   275
    EdmondsKarp& tolerance(const Tolerance& tolerance) const {
deba@2514
   276
      _tolerance = tolerance;
deba@2514
   277
      return *this;
deba@2514
   278
    } 
deba@2514
   279
deba@2514
   280
    /// \brief Returns the tolerance used by algorithm.
deba@2514
   281
    ///
deba@2514
   282
    /// Returns the tolerance used by algorithm.
deba@2514
   283
    const Tolerance& tolerance() const {
deba@2514
   284
      return tolerance;
deba@2514
   285
    } 
deba@2514
   286
deba@2514
   287
    /// \name Execution control The simplest way to execute the
deba@2514
   288
    /// algorithm is to use the \c run() member functions.
deba@2514
   289
    /// \n
deba@2514
   290
    /// If you need more control on initial solution or
deba@2514
   291
    /// execution then you have to call one \ref init() function and then
deba@2514
   292
    /// the start() or multiple times the \c augment() member function.  
deba@2514
   293
    
deba@2514
   294
    ///@{
deba@2514
   295
deba@2034
   296
    /// \brief Initializes the algorithm
deba@2034
   297
    /// 
deba@2034
   298
    /// It sets the flow to empty flow.
deba@2034
   299
    void init() {
deba@2514
   300
      createStructures();
deba@2034
   301
      for (EdgeIt it(_graph); it != INVALID; ++it) {
deba@2514
   302
        _flow->set(it, 0);
deba@2034
   303
      }
deba@2514
   304
      _flow_value = 0;
deba@2034
   305
    }
deba@2034
   306
    
deba@2034
   307
    /// \brief Initializes the algorithm
deba@2034
   308
    /// 
deba@2514
   309
    /// Initializes the flow to the \c flowMap. The \c flowMap should
deba@2514
   310
    /// contain a feasible flow, ie. in each node excluding the source
deba@2514
   311
    /// and the target the incoming flow should be equal to the
deba@2514
   312
    /// outgoing flow.
deba@2514
   313
    template <typename FlowMap>
deba@2514
   314
    void flowInit(const FlowMap& flowMap) {
deba@2514
   315
      createStructures();
deba@2514
   316
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@2514
   317
	_flow->set(e, flowMap[e]);
deba@2514
   318
      }
deba@2514
   319
      _flow_value = 0;
deba@2034
   320
      for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
deba@2514
   321
        _flow_value += (*_flow)[jt];
deba@2034
   322
      }
deba@2034
   323
      for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
deba@2514
   324
        _flow_value -= (*_flow)[jt];
deba@2034
   325
      }
deba@2034
   326
    }
deba@2034
   327
deba@2034
   328
    /// \brief Initializes the algorithm
deba@2034
   329
    /// 
deba@2514
   330
    /// Initializes the flow to the \c flowMap. The \c flowMap should
deba@2514
   331
    /// contain a feasible flow, ie. in each node excluding the source
deba@2514
   332
    /// and the target the incoming flow should be equal to the
deba@2514
   333
    /// outgoing flow.  
deba@2514
   334
    /// \return %False when the given flowMap does not contain
deba@2514
   335
    /// feasible flow.
deba@2514
   336
    template <typename FlowMap>
deba@2514
   337
    bool checkedFlowInit(const FlowMap& flowMap) {
deba@2514
   338
      createStructures();
deba@2514
   339
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@2514
   340
	_flow->set(e, flowMap[e]);
deba@2034
   341
      }
deba@2034
   342
      for (NodeIt it(_graph); it != INVALID; ++it) {
deba@2034
   343
        if (it == _source || it == _target) continue;
deba@2514
   344
        Value outFlow = 0;
deba@2034
   345
        for (OutEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
deba@2514
   346
          outFlow += (*_flow)[jt];
deba@2034
   347
        }
deba@2514
   348
        Value inFlow = 0;
deba@2034
   349
        for (InEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
deba@2514
   350
          inFlow += (*_flow)[jt];
deba@2034
   351
        }
deba@2034
   352
        if (_tolerance.different(outFlow, inFlow)) {
deba@2034
   353
          return false;
deba@2034
   354
        }
deba@2034
   355
      }
deba@2034
   356
      for (EdgeIt it(_graph); it != INVALID; ++it) {
deba@2514
   357
        if (_tolerance.less((*_flow)[it], 0)) return false;
deba@2514
   358
        if (_tolerance.less((*_capacity)[it], (*_flow)[it])) return false;
deba@2514
   359
      }
deba@2514
   360
      _flow_value = 0;
deba@2514
   361
      for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
deba@2514
   362
        _flow_value += (*_flow)[jt];
deba@2514
   363
      }
deba@2514
   364
      for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
deba@2514
   365
        _flow_value -= (*_flow)[jt];
deba@2034
   366
      }
deba@2034
   367
      return true;
deba@2034
   368
    }
deba@2034
   369
deba@2034
   370
    /// \brief Augment the solution on an edge shortest path.
deba@2034
   371
    /// 
deba@2034
   372
    /// Augment the solution on an edge shortest path. It search an
deba@2034
   373
    /// edge shortest path between the source and the target
deba@2034
   374
    /// in the residual graph with the bfs algoritm.
deba@2034
   375
    /// Then it increase the flow on this path with the minimal residual
deba@2034
   376
    /// capacity on the path. If there is not such path it gives back
deba@2034
   377
    /// false.
deba@2034
   378
    /// \return %False when the augmenting is not success so the
deba@2034
   379
    /// current flow is a feasible and optimal solution.
deba@2034
   380
    bool augment() {
deba@2514
   381
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@2514
   382
	_pred->set(n, INVALID);
deba@2514
   383
      }
deba@2514
   384
      
deba@2514
   385
      int first = 0, last = 1;
deba@2514
   386
      
deba@2514
   387
      _queue[0] = _source;
deba@2514
   388
      _pred->set(_source, OutEdgeIt(_graph, _source));
deba@2034
   389
deba@2514
   390
      while (first != last && (*_pred)[_target] == INVALID) {
deba@2514
   391
	Node n = _queue[first++];
deba@2514
   392
	
deba@2514
   393
	for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
deba@2514
   394
	  Value rem = (*_capacity)[e] - (*_flow)[e];
deba@2514
   395
	  Node t = _graph.target(e);
deba@2514
   396
	  if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
deba@2514
   397
	    _pred->set(t, e);
deba@2514
   398
	    _queue[last++] = t;
deba@2514
   399
	  }
deba@2514
   400
	}
deba@2514
   401
	for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
deba@2514
   402
	  Value rem = (*_flow)[e];
deba@2514
   403
	  Node t = _graph.source(e);
deba@2514
   404
	  if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
deba@2514
   405
	    _pred->set(t, e);
deba@2514
   406
	    _queue[last++] = t;
deba@2514
   407
	  }
deba@2514
   408
	}
deba@2514
   409
      }
deba@2034
   410
deba@2514
   411
      if ((*_pred)[_target] != INVALID) {
deba@2514
   412
	Node n = _target;
deba@2514
   413
	Edge e = (*_pred)[n];
deba@2514
   414
deba@2514
   415
	Value prem = (*_capacity)[e] - (*_flow)[e];
deba@2514
   416
	n = _graph.source(e);
deba@2514
   417
	while (n != _source) {
deba@2514
   418
	  e = (*_pred)[n];
deba@2514
   419
	  if (_graph.target(e) == n) {
deba@2514
   420
	    Value rem = (*_capacity)[e] - (*_flow)[e];
deba@2514
   421
	    if (rem < prem) prem = rem;
deba@2514
   422
	    n = _graph.source(e);
deba@2514
   423
	  } else {
deba@2514
   424
	    Value rem = (*_flow)[e];
deba@2514
   425
	    if (rem < prem) prem = rem;
deba@2514
   426
	    n = _graph.target(e);   
deba@2514
   427
	  } 
deba@2514
   428
	}
deba@2514
   429
deba@2514
   430
	n = _target;
deba@2514
   431
	e = (*_pred)[n];
deba@2514
   432
deba@2514
   433
	_flow->set(e, (*_flow)[e] + prem);
deba@2514
   434
	n = _graph.source(e);
deba@2514
   435
	while (n != _source) {
deba@2514
   436
	  e = (*_pred)[n];
deba@2514
   437
	  if (_graph.target(e) == n) {
deba@2514
   438
	    _flow->set(e, (*_flow)[e] + prem);
deba@2514
   439
	    n = _graph.source(e);
deba@2514
   440
	  } else {
deba@2514
   441
	    _flow->set(e, (*_flow)[e] - prem);
deba@2514
   442
	    n = _graph.target(e);   
deba@2514
   443
	  } 
deba@2514
   444
	}
deba@2514
   445
deba@2514
   446
	_flow_value += prem;	
deba@2514
   447
	return true;
deba@2514
   448
      } else {
deba@2514
   449
	return false;
deba@2034
   450
      }
deba@2034
   451
    }
deba@2034
   452
deba@2034
   453
    /// \brief Executes the algorithm
deba@2034
   454
    ///
deba@2034
   455
    /// It runs augmenting phases until the optimal solution is reached. 
deba@2034
   456
    void start() {
deba@2034
   457
      while (augment()) {}
deba@2034
   458
    }
deba@2034
   459
deba@2034
   460
    /// \brief runs the algorithm.
deba@2034
   461
    /// 
deba@2034
   462
    /// It is just a shorthand for:
deba@2059
   463
    ///
deba@2059
   464
    ///\code 
deba@2034
   465
    /// ek.init();
deba@2034
   466
    /// ek.start();
deba@2059
   467
    ///\endcode
deba@2034
   468
    void run() {
deba@2034
   469
      init();
deba@2034
   470
      start();
deba@2034
   471
    }
deba@2034
   472
deba@2514
   473
    /// @}
deba@2514
   474
deba@2514
   475
    /// \name Query Functions
deba@2522
   476
    /// The result of the Edmonds-Karp algorithm can be obtained using these
deba@2514
   477
    /// functions.\n
deba@2514
   478
    /// Before the use of these functions,
deba@2514
   479
    /// either run() or start() must be called.
deba@2514
   480
    
deba@2514
   481
    ///@{
deba@2514
   482
deba@2514
   483
    /// \brief Returns the value of the maximum flow.
deba@2514
   484
    ///
deba@2514
   485
    /// Returns the value of the maximum flow by returning the excess
deba@2514
   486
    /// of the target node \c t. This value equals to the value of
deba@2514
   487
    /// the maximum flow already after the first phase.
deba@2514
   488
    Value flowValue() const {
deba@2514
   489
      return _flow_value;
deba@2514
   490
    }
deba@2514
   491
deba@2514
   492
deba@2514
   493
    /// \brief Returns the flow on the edge.
deba@2514
   494
    ///
deba@2514
   495
    /// Sets the \c flowMap to the flow on the edges. This method can
deba@2514
   496
    /// be called after the second phase of algorithm.
deba@2514
   497
    Value flow(const Edge& edge) const {
deba@2514
   498
      return (*_flow)[edge];
deba@2514
   499
    }
deba@2514
   500
deba@2514
   501
    /// \brief Returns true when the node is on the source side of minimum cut.
deba@2514
   502
    ///
deba@2514
   503
deba@2514
   504
    /// Returns true when the node is on the source side of minimum
deba@2514
   505
    /// cut. This method can be called both after running \ref
deba@2514
   506
    /// startFirstPhase() and \ref startSecondPhase().
deba@2514
   507
    bool minCut(const Node& node) const {
deba@2514
   508
      return (*_pred)[node] != INVALID;
deba@2514
   509
    }
deba@2514
   510
deba@2034
   511
    /// \brief Returns a minimum value cut.
deba@2034
   512
    ///
deba@2034
   513
    /// Sets \c cut to the characteristic vector of a minimum value cut
deba@2034
   514
    /// It simply calls the minMinCut member.
deba@2037
   515
    /// \retval cut Write node bool map. 
deba@2034
   516
    template <typename CutMap>
deba@2514
   517
    void minCutMap(CutMap& cutMap) const {
deba@2514
   518
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@2514
   519
	cutMap.set(n, (*_pred)[n] != INVALID);
deba@2514
   520
      }
deba@2514
   521
      cutMap.set(_source, true);
deba@2514
   522
    }    
deba@2034
   523
deba@2514
   524
    /// @}
deba@2034
   525
deba@2034
   526
  };
deba@2034
   527
deba@2034
   528
}
deba@2034
   529
deba@2034
   530
#endif