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