lemon/edmonds_karp.h
author deba
Sun, 25 Nov 2007 22:56:44 +0000
changeset 2521 05c0ba99cc27
parent 2391 14a343be7a5a
child 2522 616c019215c4
permissions -rw-r--r--
Bugfix: using read-write map instead reference map
     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/tolerance.h>
    27 #include <vector>
    28 
    29 namespace lemon {
    30 
    31   /// \brief Default traits class of EdmondsKarp class.
    32   ///
    33   /// Default traits class of EdmondsKarp class.
    34   /// \param _Graph Graph type.
    35   /// \param _CapacityMap Type of capacity map.
    36   template <typename _Graph, typename _CapacityMap>
    37   struct EdmondsKarpDefaultTraits {
    38 
    39     /// \brief The graph type the algorithm runs on. 
    40     typedef _Graph Graph;
    41 
    42     /// \brief The type of the map that stores the edge capacities.
    43     ///
    44     /// The type of the map that stores the edge capacities.
    45     /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
    46     typedef _CapacityMap CapacityMap;
    47 
    48     /// \brief The type of the length of the edges.
    49     typedef typename CapacityMap::Value Value;
    50 
    51     /// \brief The map type that stores the flow values.
    52     ///
    53     /// The map type that stores the flow values. 
    54     /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
    55     typedef typename Graph::template EdgeMap<Value> FlowMap;
    56 
    57     /// \brief Instantiates a FlowMap.
    58     ///
    59     /// This function instantiates a \ref FlowMap. 
    60     /// \param graph The graph, to which we would like to define the flow map.
    61     static FlowMap* createFlowMap(const Graph& graph) {
    62       return new FlowMap(graph);
    63     }
    64 
    65     /// \brief The tolerance used by the algorithm
    66     ///
    67     /// The tolerance used by the algorithm to handle inexact computation.
    68     typedef Tolerance<Value> Tolerance;
    69 
    70   };
    71 
    72   /// \ingroup max_flow
    73   ///
    74   /// \brief Edmonds-Karp algorithms class.
    75   ///
    76   /// This class provides an implementation of the \e Edmonds-Karp \e
    77   /// algorithm producing a flow of maximum value in a directed
    78   /// graphs. The Edmonds-Karp algorithm is slower than the Preflow
    79   /// algorithm but it has an advantage of the step-by-step execution
    80   /// control with feasible flow solutions. The \e source node, the \e
    81   /// target node, the \e capacity of the edges and the \e starting \e
    82   /// flow value of the edges should be passed to the algorithm
    83   /// through the constructor.
    84   ///
    85   /// The time complexity of the algorithm is \f$ O(nm^2) \f$ in
    86   /// worst case.  Always try the preflow algorithm instead of this if
    87   /// you just want to compute the optimal flow.
    88   ///
    89   /// \param _Graph The directed graph type the algorithm runs on.
    90   /// \param _CapacityMap The capacity map type.
    91   /// \param _Traits Traits class to set various data types used by
    92   /// the algorithm.  The default traits class is \ref
    93   /// EdmondsKarpDefaultTraits.  See \ref EdmondsKarpDefaultTraits for the
    94   /// documentation of a Edmonds-Karp traits class. 
    95   ///
    96   /// \author Balazs Dezso 
    97 #ifdef DOXYGEN
    98   template <typename _Graph, typename _CapacityMap, typename _Traits>
    99 #else 
   100   template <typename _Graph,
   101 	    typename _CapacityMap = typename _Graph::template EdgeMap<int>,
   102             typename _Traits = EdmondsKarpDefaultTraits<_Graph, _CapacityMap> >
   103 #endif
   104   class EdmondsKarp {
   105   public:
   106 
   107     typedef _Traits Traits;
   108     typedef typename Traits::Graph Graph;
   109     typedef typename Traits::CapacityMap CapacityMap;
   110     typedef typename Traits::Value Value; 
   111 
   112     typedef typename Traits::FlowMap FlowMap;
   113     typedef typename Traits::Tolerance Tolerance;
   114 
   115     /// \brief \ref Exception for the case when the source equals the target.
   116     ///
   117     /// \ref Exception for the case when the source equals the target.
   118     ///
   119     class InvalidArgument : public lemon::LogicError {
   120     public:
   121       virtual const char* what() const throw() {
   122 	return "lemon::EdmondsKarp::InvalidArgument";
   123       }
   124     };
   125 
   126 
   127   private:
   128 
   129     GRAPH_TYPEDEFS(typename Graph);
   130     typedef typename Graph::template NodeMap<Edge> PredMap;
   131     
   132     const Graph& _graph;
   133     const CapacityMap* _capacity;
   134 
   135     Node _source, _target;
   136 
   137     FlowMap* _flow;
   138     bool _local_flow;
   139 
   140     PredMap* _pred;
   141     std::vector<Node> _queue;
   142     
   143     Tolerance _tolerance;
   144     Value _flow_value;
   145 
   146     void createStructures() {
   147       if (!_flow) {
   148 	_flow = Traits::createFlowMap(_graph);
   149 	_local_flow = true;
   150       }
   151       if (!_pred) {
   152 	_pred = new PredMap(_graph);
   153       }
   154       _queue.resize(countNodes(_graph));
   155     }
   156 
   157     void destroyStructures() {
   158       if (_local_flow) {
   159 	delete _flow;
   160       }
   161       if (_pred) {
   162 	delete _pred;
   163       }
   164     }
   165     
   166   public:
   167 
   168     ///\name Named template parameters
   169 
   170     ///@{
   171 
   172     template <typename _FlowMap>
   173     struct DefFlowMapTraits : public Traits {
   174       typedef _FlowMap FlowMap;
   175       static FlowMap *createFlowMap(const Graph&) {
   176 	throw UninitializedParameter();
   177       }
   178     };
   179 
   180     /// \brief \ref named-templ-param "Named parameter" for setting
   181     /// FlowMap type
   182     ///
   183     /// \ref named-templ-param "Named parameter" for setting FlowMap
   184     /// type
   185     template <typename _FlowMap>
   186     struct DefFlowMap 
   187       : public EdmondsKarp<Graph, CapacityMap, DefFlowMapTraits<_FlowMap> > {
   188       typedef EdmondsKarp<Graph, CapacityMap, DefFlowMapTraits<_FlowMap> > 
   189       Create;
   190     };
   191 
   192 
   193     /// @}
   194 
   195     /// \brief The constructor of the class.
   196     ///
   197     /// The constructor of the class. 
   198     /// \param graph The directed graph the algorithm runs on. 
   199     /// \param capacity The capacity of the edges. 
   200     /// \param source The source node.
   201     /// \param target The target node.
   202     EdmondsKarp(const Graph& graph, const CapacityMap& capacity,
   203 		Node source, Node target)
   204       : _graph(graph), _capacity(&capacity), _source(source), _target(target),
   205 	_flow(0), _local_flow(false), _pred(0), _tolerance(), _flow_value()
   206     {
   207       if (_source == _target) {
   208         throw InvalidArgument();
   209       }
   210     }
   211 
   212     /// \brief Destrcutor.
   213     ///
   214     /// Destructor.
   215     ~EdmondsKarp() {
   216       destroyStructures();
   217     }
   218 
   219     /// \brief Sets the capacity map.
   220     ///
   221     /// Sets the capacity map.
   222     /// \return \c (*this)
   223     EdmondsKarp& capacityMap(const CapacityMap& map) {
   224       _capacity = &map;
   225       return *this;
   226     }
   227 
   228     /// \brief Sets the flow map.
   229     ///
   230     /// Sets the flow map.
   231     /// \return \c (*this)
   232     EdmondsKarp& flowMap(FlowMap& map) {
   233       if (_local_flow) {
   234 	delete _flow;
   235 	_local_flow = false;
   236       }
   237       _flow = &map;
   238       return *this;
   239     }
   240 
   241     /// \brief Returns the flow map.
   242     ///
   243     /// \return The flow map.
   244     const FlowMap& flowMap() {
   245       return *_flow;
   246     }
   247 
   248     /// \brief Sets the source node.
   249     ///
   250     /// Sets the source node.
   251     /// \return \c (*this)
   252     EdmondsKarp& source(const Node& node) {
   253       _source = node;
   254       return *this;
   255     }
   256 
   257     /// \brief Sets the target node.
   258     ///
   259     /// Sets the target node.
   260     /// \return \c (*this)
   261     EdmondsKarp& target(const Node& node) {
   262       _target = node;
   263       return *this;
   264     }
   265 
   266     /// \brief Sets the tolerance used by algorithm.
   267     ///
   268     /// Sets the tolerance used by algorithm.
   269     EdmondsKarp& tolerance(const Tolerance& tolerance) const {
   270       _tolerance = tolerance;
   271       return *this;
   272     } 
   273 
   274     /// \brief Returns the tolerance used by algorithm.
   275     ///
   276     /// Returns the tolerance used by algorithm.
   277     const Tolerance& tolerance() const {
   278       return tolerance;
   279     } 
   280 
   281     /// \name Execution control The simplest way to execute the
   282     /// algorithm is to use the \c run() member functions.
   283     /// \n
   284     /// If you need more control on initial solution or
   285     /// execution then you have to call one \ref init() function and then
   286     /// the start() or multiple times the \c augment() member function.  
   287     
   288     ///@{
   289 
   290     /// \brief Initializes the algorithm
   291     /// 
   292     /// It sets the flow to empty flow.
   293     void init() {
   294       createStructures();
   295       for (EdgeIt it(_graph); it != INVALID; ++it) {
   296         _flow->set(it, 0);
   297       }
   298       _flow_value = 0;
   299     }
   300     
   301     /// \brief Initializes the algorithm
   302     /// 
   303     /// Initializes the flow to the \c flowMap. The \c flowMap should
   304     /// contain a feasible flow, ie. in each node excluding the source
   305     /// and the target the incoming flow should be equal to the
   306     /// outgoing flow.
   307     template <typename FlowMap>
   308     void flowInit(const FlowMap& flowMap) {
   309       createStructures();
   310       for (EdgeIt e(_graph); e != INVALID; ++e) {
   311 	_flow->set(e, flowMap[e]);
   312       }
   313       _flow_value = 0;
   314       for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
   315         _flow_value += (*_flow)[jt];
   316       }
   317       for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
   318         _flow_value -= (*_flow)[jt];
   319       }
   320     }
   321 
   322     /// \brief Initializes the algorithm
   323     /// 
   324     /// Initializes the flow to the \c flowMap. The \c flowMap should
   325     /// contain a feasible flow, ie. in each node excluding the source
   326     /// and the target the incoming flow should be equal to the
   327     /// outgoing flow.  
   328     /// \return %False when the given flowMap does not contain
   329     /// feasible flow.
   330     template <typename FlowMap>
   331     bool checkedFlowInit(const FlowMap& flowMap) {
   332       createStructures();
   333       for (EdgeIt e(_graph); e != INVALID; ++e) {
   334 	_flow->set(e, flowMap[e]);
   335       }
   336       for (NodeIt it(_graph); it != INVALID; ++it) {
   337         if (it == _source || it == _target) continue;
   338         Value outFlow = 0;
   339         for (OutEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
   340           outFlow += (*_flow)[jt];
   341         }
   342         Value inFlow = 0;
   343         for (InEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
   344           inFlow += (*_flow)[jt];
   345         }
   346         if (_tolerance.different(outFlow, inFlow)) {
   347           return false;
   348         }
   349       }
   350       for (EdgeIt it(_graph); it != INVALID; ++it) {
   351         if (_tolerance.less((*_flow)[it], 0)) return false;
   352         if (_tolerance.less((*_capacity)[it], (*_flow)[it])) return false;
   353       }
   354       _flow_value = 0;
   355       for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
   356         _flow_value += (*_flow)[jt];
   357       }
   358       for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
   359         _flow_value -= (*_flow)[jt];
   360       }
   361       return true;
   362     }
   363 
   364     /// \brief Augment the solution on an edge shortest path.
   365     /// 
   366     /// Augment the solution on an edge shortest path. It search an
   367     /// edge shortest path between the source and the target
   368     /// in the residual graph with the bfs algoritm.
   369     /// Then it increase the flow on this path with the minimal residual
   370     /// capacity on the path. If there is not such path it gives back
   371     /// false.
   372     /// \return %False when the augmenting is not success so the
   373     /// current flow is a feasible and optimal solution.
   374     bool augment() {
   375       for (NodeIt n(_graph); n != INVALID; ++n) {
   376 	_pred->set(n, INVALID);
   377       }
   378       
   379       int first = 0, last = 1;
   380       
   381       _queue[0] = _source;
   382       _pred->set(_source, OutEdgeIt(_graph, _source));
   383 
   384       while (first != last && (*_pred)[_target] == INVALID) {
   385 	Node n = _queue[first++];
   386 	
   387 	for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
   388 	  Value rem = (*_capacity)[e] - (*_flow)[e];
   389 	  Node t = _graph.target(e);
   390 	  if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
   391 	    _pred->set(t, e);
   392 	    _queue[last++] = t;
   393 	  }
   394 	}
   395 	for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
   396 	  Value rem = (*_flow)[e];
   397 	  Node t = _graph.source(e);
   398 	  if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
   399 	    _pred->set(t, e);
   400 	    _queue[last++] = t;
   401 	  }
   402 	}
   403       }
   404 
   405       if ((*_pred)[_target] != INVALID) {
   406 	Node n = _target;
   407 	Edge e = (*_pred)[n];
   408 
   409 	Value prem = (*_capacity)[e] - (*_flow)[e];
   410 	n = _graph.source(e);
   411 	while (n != _source) {
   412 	  e = (*_pred)[n];
   413 	  if (_graph.target(e) == n) {
   414 	    Value rem = (*_capacity)[e] - (*_flow)[e];
   415 	    if (rem < prem) prem = rem;
   416 	    n = _graph.source(e);
   417 	  } else {
   418 	    Value rem = (*_flow)[e];
   419 	    if (rem < prem) prem = rem;
   420 	    n = _graph.target(e);   
   421 	  } 
   422 	}
   423 
   424 	n = _target;
   425 	e = (*_pred)[n];
   426 
   427 	_flow->set(e, (*_flow)[e] + prem);
   428 	n = _graph.source(e);
   429 	while (n != _source) {
   430 	  e = (*_pred)[n];
   431 	  if (_graph.target(e) == n) {
   432 	    _flow->set(e, (*_flow)[e] + prem);
   433 	    n = _graph.source(e);
   434 	  } else {
   435 	    _flow->set(e, (*_flow)[e] - prem);
   436 	    n = _graph.target(e);   
   437 	  } 
   438 	}
   439 
   440 	_flow_value += prem;	
   441 	return true;
   442       } else {
   443 	return false;
   444       }
   445     }
   446 
   447     /// \brief Executes the algorithm
   448     ///
   449     /// It runs augmenting phases until the optimal solution is reached. 
   450     void start() {
   451       while (augment()) {}
   452     }
   453 
   454     /// \brief runs the algorithm.
   455     /// 
   456     /// It is just a shorthand for:
   457     ///
   458     ///\code 
   459     /// ek.init();
   460     /// ek.start();
   461     ///\endcode
   462     void run() {
   463       init();
   464       start();
   465     }
   466 
   467     /// @}
   468 
   469     /// \name Query Functions
   470     /// The result of the %Dijkstra algorithm can be obtained using these
   471     /// functions.\n
   472     /// Before the use of these functions,
   473     /// either run() or start() must be called.
   474     
   475     ///@{
   476 
   477     /// \brief Returns the value of the maximum flow.
   478     ///
   479     /// Returns the value of the maximum flow by returning the excess
   480     /// of the target node \c t. This value equals to the value of
   481     /// the maximum flow already after the first phase.
   482     Value flowValue() const {
   483       return _flow_value;
   484     }
   485 
   486 
   487     /// \brief Returns the flow on the edge.
   488     ///
   489     /// Sets the \c flowMap to the flow on the edges. This method can
   490     /// be called after the second phase of algorithm.
   491     Value flow(const Edge& edge) const {
   492       return (*_flow)[edge];
   493     }
   494 
   495     /// \brief Returns true when the node is on the source side of minimum cut.
   496     ///
   497 
   498     /// Returns true when the node is on the source side of minimum
   499     /// cut. This method can be called both after running \ref
   500     /// startFirstPhase() and \ref startSecondPhase().
   501     bool minCut(const Node& node) const {
   502       return (*_pred)[node] != INVALID;
   503     }
   504 
   505     /// \brief Returns a minimum value cut.
   506     ///
   507     /// Sets \c cut to the characteristic vector of a minimum value cut
   508     /// It simply calls the minMinCut member.
   509     /// \retval cut Write node bool map. 
   510     template <typename CutMap>
   511     void minCutMap(CutMap& cutMap) const {
   512       for (NodeIt n(_graph); n != INVALID; ++n) {
   513 	cutMap.set(n, (*_pred)[n] != INVALID);
   514       }
   515       cutMap.set(_source, true);
   516     }    
   517 
   518     /// @}
   519 
   520   };
   521 
   522 }
   523 
   524 #endif