lemon/edmonds_karp.h
author deba
Fri, 29 Sep 2006 11:26:29 +0000
changeset 2224 f973894da54e
parent 2113 48ec8161f9e1
child 2376 0ed45a6c74b1
permissions -rw-r--r--
Moving the file into correct group
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