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