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