lemon/edmonds_karp.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2113 48ec8161f9e1
child 2376 0ed45a6c74b1
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
     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 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