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