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