lemon/edmonds_karp.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2113 48ec8161f9e1
child 2376 0ed45a6c74b1
permissions -rw-r--r--
Update the Path concept
Concept check for paths

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

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

The tests have been modified to the current implementation
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
 *
deba@2034
     5
 * Copyright (C) 2003-2006
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@2034
    23
/// \ingroup flowalgs
deba@2034
    24
/// \brief Implementation of the Edmonds-Karp algorithm.
deba@2034
    25
deba@2034
    26
#include <lemon/graph_adaptor.h>
deba@2034
    27
#include <lemon/tolerance.h>
deba@2034
    28
#include <lemon/bfs.h>
deba@2034
    29
deba@2034
    30
namespace lemon {
deba@2034
    31
deba@2034
    32
  /// \ingroup flowalgs
deba@2034
    33
  /// \brief Edmonds-Karp algorithms class.
deba@2034
    34
  ///
deba@2034
    35
  /// This class provides an implementation of the \e Edmonds-Karp \e
deba@2034
    36
  /// algorithm producing a flow of maximum value in a directed
deba@2034
    37
  /// graph. The Edmonds-Karp algorithm is slower than the Preflow algorithm
deba@2034
    38
  /// but it has an advantage of the step-by-step execution control with
deba@2034
    39
  /// feasible flow solutions. The \e source node, the \e target node, the \e
deba@2034
    40
  /// capacity of the edges and the \e starting \e flow value of the
deba@2034
    41
  /// edges should be passed to the algorithm through the
deba@2036
    42
  /// constructor.
deba@2034
    43
  ///
deba@2059
    44
  /// The time complexity of the algorithm is \f$ O(n * e^2) \f$ in
deba@2059
    45
  /// worst case.  Always try the preflow algorithm instead of this if
deba@2113
    46
  /// you just want to compute the optimal flow.
deba@2034
    47
  ///
deba@2034
    48
  /// \param _Graph The directed graph type the algorithm runs on.
deba@2034
    49
  /// \param _Number The number type of the capacities and the flow values.
deba@2034
    50
  /// \param _CapacityMap The capacity map type.
deba@2034
    51
  /// \param _FlowMap The flow map type.
deba@2034
    52
  /// \param _Tolerance The tolerance class to handle computation problems.
deba@2034
    53
  ///
deba@2034
    54
  /// \author Balazs Dezso 
deba@2059
    55
#ifdef DOXYGEN
deba@2059
    56
  template <typename _Graph, typename _Number,
deba@2059
    57
	    typename _CapacityMap, typename _FlowMap, typename _Tolerance>
deba@2059
    58
#else
deba@2034
    59
  template <typename _Graph, typename _Number,
deba@2034
    60
	    typename _CapacityMap = typename _Graph::template EdgeMap<_Number>,
deba@2034
    61
            typename _FlowMap = typename _Graph::template EdgeMap<_Number>,
deba@2034
    62
	    typename _Tolerance = Tolerance<_Number> >
deba@2059
    63
#endif
deba@2034
    64
  class EdmondsKarp {
deba@2034
    65
  public:
deba@2034
    66
deba@2034
    67
    /// \brief \ref Exception for the case when the source equals the target.
deba@2034
    68
    ///
deba@2034
    69
    /// \ref Exception for the case when the source equals the target.
deba@2034
    70
    ///
deba@2034
    71
    class InvalidArgument : public lemon::LogicError {
deba@2034
    72
    public:
alpar@2151
    73
      virtual const char* what() const throw() {
deba@2034
    74
	return "lemon::EdmondsKarp::InvalidArgument";
deba@2034
    75
      }
deba@2034
    76
    };
deba@2034
    77
deba@2034
    78
deba@2034
    79
    /// \brief The graph type the algorithm runs on. 
deba@2034
    80
    typedef _Graph Graph;
deba@2034
    81
    /// \brief The value type of the algorithms.
deba@2034
    82
    typedef _Number Number;
deba@2034
    83
    /// \brief The capacity map on the edges.
deba@2034
    84
    typedef _CapacityMap CapacityMap;
deba@2034
    85
    /// \brief The flow map on the edges.
deba@2034
    86
    typedef _FlowMap FlowMap;
deba@2034
    87
    /// \brief The tolerance used by the algorithm.
deba@2034
    88
    typedef _Tolerance Tolerance;
deba@2034
    89
deba@2034
    90
    typedef ResGraphAdaptor<Graph, Number, CapacityMap, 
deba@2034
    91
                            FlowMap, Tolerance> ResGraph;
deba@2034
    92
deba@2034
    93
  private:
deba@2034
    94
deba@2034
    95
    typedef typename Graph::Node Node;
deba@2034
    96
    typedef typename Graph::Edge Edge;
deba@2034
    97
    
deba@2034
    98
    typedef typename Graph::NodeIt NodeIt;
deba@2034
    99
    typedef typename Graph::EdgeIt EdgeIt;
deba@2034
   100
    typedef typename Graph::InEdgeIt InEdgeIt;
deba@2034
   101
    typedef typename Graph::OutEdgeIt OutEdgeIt;
deba@2034
   102
    
deba@2034
   103
  public:
deba@2034
   104
deba@2034
   105
    /// \brief The constructor of the class.
deba@2034
   106
    ///
deba@2034
   107
    /// The constructor of the class. 
deba@2037
   108
    /// \param graph The directed graph the algorithm runs on. 
deba@2037
   109
    /// \param source The source node.
deba@2037
   110
    /// \param target The target node.
deba@2037
   111
    /// \param capacity The capacity of the edges. 
deba@2037
   112
    /// \param flow The flow of the edges. 
deba@2037
   113
    /// \param tolerance Tolerance class.
deba@2034
   114
    EdmondsKarp(const Graph& graph, Node source, Node target,
deba@2034
   115
                const CapacityMap& capacity, FlowMap& flow, 
deba@2034
   116
                const Tolerance& tolerance = Tolerance())
deba@2034
   117
      : _graph(graph), _capacity(capacity), _flow(flow), 
deba@2034
   118
        _tolerance(tolerance), _resgraph(graph, capacity, flow, tolerance), 
deba@2034
   119
        _source(source), _target(target) 
deba@2034
   120
    {
deba@2034
   121
      if (_source == _target) {
deba@2034
   122
        throw InvalidArgument();
deba@2034
   123
      }
deba@2034
   124
    }
deba@2034
   125
deba@2034
   126
    /// \brief Initializes the algorithm
deba@2034
   127
    /// 
deba@2034
   128
    /// It sets the flow to empty flow.
deba@2034
   129
    void init() {
deba@2034
   130
      for (EdgeIt it(_graph); it != INVALID; ++it) {
deba@2034
   131
        _flow.set(it, 0);
deba@2034
   132
      }
deba@2034
   133
      _value = 0;
deba@2034
   134
    }
deba@2034
   135
    
deba@2034
   136
    /// \brief Initializes the algorithm
deba@2034
   137
    /// 
deba@2034
   138
    /// If the flow map initially flow this let the flow map
deba@2034
   139
    /// unchanged but the flow value will be set by the flow
deba@2034
   140
    /// on the outedges from the source.
deba@2034
   141
    void flowInit() {
deba@2034
   142
      _value = 0;
deba@2034
   143
      for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
deba@2034
   144
        _value += _flow[jt];
deba@2034
   145
      }
deba@2034
   146
      for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
deba@2034
   147
        _value -= _flow[jt];
deba@2034
   148
      }
deba@2034
   149
    }
deba@2034
   150
deba@2034
   151
    /// \brief Initializes the algorithm
deba@2034
   152
    /// 
deba@2034
   153
    /// If the flow map initially flow this let the flow map
deba@2034
   154
    /// unchanged but the flow value will be set by the flow
deba@2034
   155
    /// on the outedges from the source. It also checks that
deba@2034
   156
    /// the flow map really contains a flow.
deba@2034
   157
    /// \return %True when the flow map really a flow.
deba@2034
   158
    bool checkedFlowInit() {
deba@2034
   159
      _value = 0;
deba@2034
   160
      for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
deba@2034
   161
        _value += _flow[jt];
deba@2034
   162
      }
deba@2034
   163
      for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
deba@2034
   164
        _value -= _flow[jt];
deba@2034
   165
      }
deba@2034
   166
      for (NodeIt it(_graph); it != INVALID; ++it) {
deba@2034
   167
        if (it == _source || it == _target) continue;
deba@2034
   168
        Number outFlow = 0;
deba@2034
   169
        for (OutEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
deba@2034
   170
          outFlow += _flow[jt];
deba@2034
   171
        }
deba@2034
   172
        Number inFlow = 0;
deba@2034
   173
        for (InEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
deba@2034
   174
          inFlow += _flow[jt];
deba@2034
   175
        }
deba@2034
   176
        if (_tolerance.different(outFlow, inFlow)) {
deba@2034
   177
          return false;
deba@2034
   178
        }
deba@2034
   179
      }
deba@2034
   180
      for (EdgeIt it(_graph); it != INVALID; ++it) {
deba@2034
   181
        if (_tolerance.less(_flow[it], 0)) return false;
deba@2034
   182
        if (_tolerance.less(_capacity[it], _flow[it])) return false;
deba@2034
   183
      }
deba@2034
   184
      return true;
deba@2034
   185
    }
deba@2034
   186
deba@2034
   187
    /// \brief Augment the solution on an edge shortest path.
deba@2034
   188
    /// 
deba@2034
   189
    /// Augment the solution on an edge shortest path. It search an
deba@2034
   190
    /// edge shortest path between the source and the target
deba@2034
   191
    /// in the residual graph with the bfs algoritm.
deba@2034
   192
    /// Then it increase the flow on this path with the minimal residual
deba@2034
   193
    /// capacity on the path. If there is not such path it gives back
deba@2034
   194
    /// false.
deba@2034
   195
    /// \return %False when the augmenting is not success so the
deba@2034
   196
    /// current flow is a feasible and optimal solution.
deba@2034
   197
    bool augment() {
deba@2034
   198
      typename Bfs<ResGraph>
deba@2034
   199
      ::template DefDistMap<NullMap<Node, int> >
deba@2034
   200
      ::Create bfs(_resgraph);
deba@2034
   201
deba@2034
   202
      NullMap<Node, int> distMap;
deba@2034
   203
      bfs.distMap(distMap);
deba@2034
   204
      
deba@2034
   205
      bfs.init();
deba@2034
   206
      bfs.addSource(_source);
deba@2034
   207
      bfs.start(_target);
deba@2034
   208
deba@2034
   209
      if (!bfs.reached(_target)) {
deba@2034
   210
        return false;
deba@2034
   211
      }
deba@2034
   212
      Number min = _resgraph.rescap(bfs.predEdge(_target));
deba@2034
   213
      for (Node it = bfs.predNode(_target); it != _source; 
deba@2034
   214
           it = bfs.predNode(it)) {
deba@2034
   215
        if (min > _resgraph.rescap(bfs.predEdge(it))) {
deba@2034
   216
          min = _resgraph.rescap(bfs.predEdge(it));
deba@2034
   217
        }
deba@2034
   218
      } 
deba@2034
   219
      for (Node it = _target; it != _source; it = bfs.predNode(it)) {
deba@2034
   220
        _resgraph.augment(bfs.predEdge(it), min);
deba@2034
   221
      }
deba@2034
   222
      _value += min;
deba@2034
   223
      return true;
deba@2034
   224
    }
deba@2034
   225
deba@2034
   226
    /// \brief Executes the algorithm
deba@2034
   227
    ///
deba@2034
   228
    /// It runs augmenting phases until the optimal solution is reached. 
deba@2034
   229
    void start() {
deba@2034
   230
      while (augment()) {}
deba@2034
   231
    }
deba@2034
   232
deba@2034
   233
    /// \brief Gives back the current flow value.
deba@2034
   234
    ///
deba@2034
   235
    /// Gives back the current flow _value.
deba@2034
   236
    Number flowValue() const {
deba@2034
   237
      return _value;
deba@2034
   238
    }
deba@2034
   239
deba@2034
   240
    /// \brief runs the algorithm.
deba@2034
   241
    /// 
deba@2034
   242
    /// It is just a shorthand for:
deba@2059
   243
    ///
deba@2059
   244
    ///\code 
deba@2034
   245
    /// ek.init();
deba@2034
   246
    /// ek.start();
deba@2059
   247
    ///\endcode
deba@2034
   248
    void run() {
deba@2034
   249
      init();
deba@2034
   250
      start();
deba@2034
   251
    }
deba@2034
   252
deba@2034
   253
    /// \brief Returns a minimum value cut.
deba@2034
   254
    ///
deba@2034
   255
    /// Sets \c cut to the characteristic vector of a minimum value cut
deba@2034
   256
    /// It simply calls the minMinCut member.
deba@2037
   257
    /// \retval cut Write node bool map. 
deba@2034
   258
    template <typename CutMap>
deba@2034
   259
    void minCut(CutMap& cut) const {
deba@2034
   260
      minMinCut(cut);
deba@2034
   261
    }
deba@2034
   262
deba@2034
   263
    /// \brief Returns the inclusionwise minimum of the minimum value cuts.
deba@2034
   264
    ///
deba@2034
   265
    /// Sets \c cut to the characteristic vector of the minimum value cut
deba@2034
   266
    /// which is inclusionwise minimum. It is computed by processing a
deba@2034
   267
    /// bfs from the source node \c source in the residual graph.  
deba@2037
   268
    /// \retval cut Write node bool map. 
deba@2034
   269
    template <typename CutMap>
deba@2034
   270
    void minMinCut(CutMap& cut) const {
deba@2034
   271
deba@2034
   272
      typename Bfs<ResGraph>
deba@2034
   273
      ::template DefDistMap<NullMap<Node, int> >
deba@2034
   274
      ::template DefProcessedMap<CutMap>
deba@2034
   275
      ::Create bfs(_resgraph);
deba@2034
   276
deba@2034
   277
      NullMap<Node, int> distMap;
deba@2034
   278
      bfs.distMap(distMap);
deba@2034
   279
deba@2034
   280
      bfs.processedMap(cut);
deba@2034
   281
     
deba@2034
   282
      bfs.run(_source);
deba@2034
   283
    }
deba@2034
   284
deba@2034
   285
    /// \brief Returns the inclusionwise minimum of the minimum value cuts.
deba@2034
   286
    ///
deba@2034
   287
    /// Sets \c cut to the characteristic vector of the minimum value cut
deba@2034
   288
    /// which is inclusionwise minimum. It is computed by processing a
deba@2034
   289
    /// bfs from the source node \c source in the residual graph.  
deba@2037
   290
    /// \retval cut Write node bool map. 
deba@2034
   291
    template <typename CutMap>
deba@2034
   292
    void maxMinCut(CutMap& cut) const {
deba@2034
   293
deba@2034
   294
      typedef RevGraphAdaptor<const ResGraph> RevGraph;
deba@2034
   295
deba@2034
   296
      RevGraph revgraph(_resgraph);
deba@2034
   297
deba@2034
   298
      typename Bfs<RevGraph>
deba@2034
   299
      ::template DefDistMap<NullMap<Node, int> >
deba@2034
   300
      ::template DefPredMap<NullMap<Node, Edge> >
deba@2034
   301
      ::template DefProcessedMap<NotWriteMap<CutMap> >
deba@2034
   302
      ::Create bfs(revgraph);
deba@2034
   303
deba@2034
   304
      NullMap<Node, int> distMap;
deba@2034
   305
      bfs.distMap(distMap);
deba@2034
   306
deba@2034
   307
      NullMap<Node, Edge> predMap;
deba@2034
   308
      bfs.predMap(predMap);
deba@2034
   309
deba@2034
   310
      NotWriteMap<CutMap> notcut(cut);
deba@2034
   311
      bfs.processedMap(notcut);
deba@2034
   312
     
deba@2034
   313
      bfs.run(_target);
deba@2034
   314
    }
deba@2034
   315
deba@2034
   316
    /// \brief Returns the source node.
deba@2034
   317
    ///
deba@2034
   318
    /// Returns the source node.
deba@2034
   319
    /// 
deba@2034
   320
    Node source() const { 
deba@2034
   321
      return _source;
deba@2034
   322
    }
deba@2034
   323
deba@2034
   324
    /// \brief Returns the target node.
deba@2034
   325
    ///
deba@2034
   326
    /// Returns the target node.
deba@2034
   327
    /// 
deba@2034
   328
    Node target() const { 
deba@2034
   329
      return _target;
deba@2034
   330
    }
deba@2034
   331
deba@2034
   332
    /// \brief Returns a reference to capacity map.
deba@2034
   333
    ///
deba@2034
   334
    /// Returns a reference to capacity map.
deba@2034
   335
    /// 
deba@2034
   336
    const CapacityMap &capacityMap() const { 
deba@2034
   337
      return *_capacity;
deba@2034
   338
    }
deba@2034
   339
     
deba@2034
   340
    /// \brief Returns a reference to flow map.
deba@2034
   341
    ///
deba@2034
   342
    /// Returns a reference to flow map.
deba@2034
   343
    /// 
deba@2034
   344
    const FlowMap &flowMap() const { 
deba@2034
   345
      return *_flow;
deba@2034
   346
    }
deba@2034
   347
deba@2036
   348
    /// \brief Returns the tolerance used by algorithm.
deba@2036
   349
    ///
deba@2036
   350
    /// Returns the tolerance used by algorithm.
deba@2036
   351
    const Tolerance& tolerance() const {
deba@2036
   352
      return tolerance;
deba@2036
   353
    } 
deba@2036
   354
    
deba@2034
   355
  private:
deba@2034
   356
    
deba@2034
   357
    const Graph& _graph;
deba@2034
   358
    const CapacityMap& _capacity;
deba@2034
   359
    FlowMap& _flow;
deba@2034
   360
    Tolerance _tolerance;
deba@2034
   361
    
deba@2034
   362
    ResGraph _resgraph;
deba@2034
   363
    Node _source, _target;
deba@2034
   364
    Number _value;
deba@2034
   365
    
deba@2034
   366
  };
deba@2034
   367
deba@2034
   368
}
deba@2034
   369
deba@2034
   370
#endif