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