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