deba@2034: /* -*- C++ -*- deba@2034: * deba@2034: * This file is a part of LEMON, a generic C++ optimization library deba@2034: * deba@2034: * Copyright (C) 2003-2006 deba@2034: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@2034: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@2034: * deba@2034: * Permission to use, modify and distribute this software is granted deba@2034: * provided that this copyright notice appears in all copies. For deba@2034: * precise terms see the accompanying LICENSE file. deba@2034: * deba@2034: * This software is provided "AS IS" with no warranty of any kind, deba@2034: * express or implied, and with no claim as to its suitability for any deba@2034: * purpose. deba@2034: * deba@2034: */ deba@2034: deba@2034: #ifndef LEMON_EDMONDS_KARP_H deba@2034: #define LEMON_EDMONDS_KARP_H deba@2034: deba@2034: /// \file deba@2034: /// \ingroup flowalgs deba@2034: /// \brief Implementation of the Edmonds-Karp algorithm. deba@2034: deba@2034: #include deba@2034: #include deba@2034: #include deba@2034: deba@2034: namespace lemon { deba@2034: deba@2034: /// \ingroup flowalgs deba@2034: /// \brief Edmonds-Karp algorithms class. deba@2034: /// deba@2034: /// This class provides an implementation of the \e Edmonds-Karp \e deba@2034: /// algorithm producing a flow of maximum value in a directed deba@2034: /// graph. The Edmonds-Karp algorithm is slower than the Preflow algorithm deba@2034: /// but it has an advantage of the step-by-step execution control with deba@2034: /// feasible flow solutions. The \e source node, the \e target node, the \e deba@2034: /// capacity of the edges and the \e starting \e flow value of the deba@2034: /// edges should be passed to the algorithm through the deba@2036: /// constructor. deba@2034: /// deba@2059: /// The time complexity of the algorithm is \f$ O(n * e^2) \f$ in deba@2059: /// worst case. Always try the preflow algorithm instead of this if deba@2113: /// you just want to compute the optimal flow. deba@2034: /// deba@2034: /// \param _Graph The directed graph type the algorithm runs on. deba@2034: /// \param _Number The number type of the capacities and the flow values. deba@2034: /// \param _CapacityMap The capacity map type. deba@2034: /// \param _FlowMap The flow map type. deba@2034: /// \param _Tolerance The tolerance class to handle computation problems. deba@2034: /// deba@2034: /// \author Balazs Dezso deba@2059: #ifdef DOXYGEN deba@2059: template deba@2059: #else deba@2034: template , deba@2034: typename _FlowMap = typename _Graph::template EdgeMap<_Number>, deba@2034: typename _Tolerance = Tolerance<_Number> > deba@2059: #endif deba@2034: class EdmondsKarp { deba@2034: public: deba@2034: deba@2034: /// \brief \ref Exception for the case when the source equals the target. deba@2034: /// deba@2034: /// \ref Exception for the case when the source equals the target. deba@2034: /// deba@2034: class InvalidArgument : public lemon::LogicError { deba@2034: public: alpar@2151: virtual const char* what() const throw() { deba@2034: return "lemon::EdmondsKarp::InvalidArgument"; deba@2034: } deba@2034: }; deba@2034: deba@2034: deba@2034: /// \brief The graph type the algorithm runs on. deba@2034: typedef _Graph Graph; deba@2034: /// \brief The value type of the algorithms. deba@2034: typedef _Number Number; deba@2034: /// \brief The capacity map on the edges. deba@2034: typedef _CapacityMap CapacityMap; deba@2034: /// \brief The flow map on the edges. deba@2034: typedef _FlowMap FlowMap; deba@2034: /// \brief The tolerance used by the algorithm. deba@2034: typedef _Tolerance Tolerance; deba@2034: deba@2034: typedef ResGraphAdaptor ResGraph; deba@2034: deba@2034: private: deba@2034: deba@2034: typedef typename Graph::Node Node; deba@2034: typedef typename Graph::Edge Edge; deba@2034: deba@2034: typedef typename Graph::NodeIt NodeIt; deba@2034: typedef typename Graph::EdgeIt EdgeIt; deba@2034: typedef typename Graph::InEdgeIt InEdgeIt; deba@2034: typedef typename Graph::OutEdgeIt OutEdgeIt; deba@2034: deba@2034: public: deba@2034: deba@2034: /// \brief The constructor of the class. deba@2034: /// deba@2034: /// The constructor of the class. deba@2037: /// \param graph The directed graph the algorithm runs on. deba@2037: /// \param source The source node. deba@2037: /// \param target The target node. deba@2037: /// \param capacity The capacity of the edges. deba@2037: /// \param flow The flow of the edges. deba@2037: /// \param tolerance Tolerance class. deba@2034: EdmondsKarp(const Graph& graph, Node source, Node target, deba@2034: const CapacityMap& capacity, FlowMap& flow, deba@2034: const Tolerance& tolerance = Tolerance()) deba@2034: : _graph(graph), _capacity(capacity), _flow(flow), deba@2034: _tolerance(tolerance), _resgraph(graph, capacity, flow, tolerance), deba@2034: _source(source), _target(target) deba@2034: { deba@2034: if (_source == _target) { deba@2034: throw InvalidArgument(); deba@2034: } deba@2034: } deba@2034: deba@2034: /// \brief Initializes the algorithm deba@2034: /// deba@2034: /// It sets the flow to empty flow. deba@2034: void init() { deba@2034: for (EdgeIt it(_graph); it != INVALID; ++it) { deba@2034: _flow.set(it, 0); deba@2034: } deba@2034: _value = 0; deba@2034: } deba@2034: deba@2034: /// \brief Initializes the algorithm deba@2034: /// deba@2034: /// If the flow map initially flow this let the flow map deba@2034: /// unchanged but the flow value will be set by the flow deba@2034: /// on the outedges from the source. deba@2034: void flowInit() { deba@2034: _value = 0; deba@2034: for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) { deba@2034: _value += _flow[jt]; deba@2034: } deba@2034: for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) { deba@2034: _value -= _flow[jt]; deba@2034: } deba@2034: } deba@2034: deba@2034: /// \brief Initializes the algorithm deba@2034: /// deba@2034: /// If the flow map initially flow this let the flow map deba@2034: /// unchanged but the flow value will be set by the flow deba@2034: /// on the outedges from the source. It also checks that deba@2034: /// the flow map really contains a flow. deba@2034: /// \return %True when the flow map really a flow. deba@2034: bool checkedFlowInit() { deba@2034: _value = 0; deba@2034: for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) { deba@2034: _value += _flow[jt]; deba@2034: } deba@2034: for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) { deba@2034: _value -= _flow[jt]; deba@2034: } deba@2034: for (NodeIt it(_graph); it != INVALID; ++it) { deba@2034: if (it == _source || it == _target) continue; deba@2034: Number outFlow = 0; deba@2034: for (OutEdgeIt jt(_graph, it); jt != INVALID; ++jt) { deba@2034: outFlow += _flow[jt]; deba@2034: } deba@2034: Number inFlow = 0; deba@2034: for (InEdgeIt jt(_graph, it); jt != INVALID; ++jt) { deba@2034: inFlow += _flow[jt]; deba@2034: } deba@2034: if (_tolerance.different(outFlow, inFlow)) { deba@2034: return false; deba@2034: } deba@2034: } deba@2034: for (EdgeIt it(_graph); it != INVALID; ++it) { deba@2034: if (_tolerance.less(_flow[it], 0)) return false; deba@2034: if (_tolerance.less(_capacity[it], _flow[it])) return false; deba@2034: } deba@2034: return true; deba@2034: } deba@2034: deba@2034: /// \brief Augment the solution on an edge shortest path. deba@2034: /// deba@2034: /// Augment the solution on an edge shortest path. It search an deba@2034: /// edge shortest path between the source and the target deba@2034: /// in the residual graph with the bfs algoritm. deba@2034: /// Then it increase the flow on this path with the minimal residual deba@2034: /// capacity on the path. If there is not such path it gives back deba@2034: /// false. deba@2034: /// \return %False when the augmenting is not success so the deba@2034: /// current flow is a feasible and optimal solution. deba@2034: bool augment() { deba@2034: typename Bfs deba@2034: ::template DefDistMap > deba@2034: ::Create bfs(_resgraph); deba@2034: deba@2034: NullMap distMap; deba@2034: bfs.distMap(distMap); deba@2034: deba@2034: bfs.init(); deba@2034: bfs.addSource(_source); deba@2034: bfs.start(_target); deba@2034: deba@2034: if (!bfs.reached(_target)) { deba@2034: return false; deba@2034: } deba@2034: Number min = _resgraph.rescap(bfs.predEdge(_target)); deba@2034: for (Node it = bfs.predNode(_target); it != _source; deba@2034: it = bfs.predNode(it)) { deba@2034: if (min > _resgraph.rescap(bfs.predEdge(it))) { deba@2034: min = _resgraph.rescap(bfs.predEdge(it)); deba@2034: } deba@2034: } deba@2034: for (Node it = _target; it != _source; it = bfs.predNode(it)) { deba@2034: _resgraph.augment(bfs.predEdge(it), min); deba@2034: } deba@2034: _value += min; deba@2034: return true; deba@2034: } deba@2034: deba@2034: /// \brief Executes the algorithm deba@2034: /// deba@2034: /// It runs augmenting phases until the optimal solution is reached. deba@2034: void start() { deba@2034: while (augment()) {} deba@2034: } deba@2034: deba@2034: /// \brief Gives back the current flow value. deba@2034: /// deba@2034: /// Gives back the current flow _value. deba@2034: Number flowValue() const { deba@2034: return _value; deba@2034: } deba@2034: deba@2034: /// \brief runs the algorithm. deba@2034: /// deba@2034: /// It is just a shorthand for: deba@2059: /// deba@2059: ///\code deba@2034: /// ek.init(); deba@2034: /// ek.start(); deba@2059: ///\endcode deba@2034: void run() { deba@2034: init(); deba@2034: start(); deba@2034: } deba@2034: deba@2034: /// \brief Returns a minimum value cut. deba@2034: /// deba@2034: /// Sets \c cut to the characteristic vector of a minimum value cut deba@2034: /// It simply calls the minMinCut member. deba@2037: /// \retval cut Write node bool map. deba@2034: template deba@2034: void minCut(CutMap& cut) const { deba@2034: minMinCut(cut); deba@2034: } deba@2034: deba@2034: /// \brief Returns the inclusionwise minimum of the minimum value cuts. deba@2034: /// deba@2034: /// Sets \c cut to the characteristic vector of the minimum value cut deba@2034: /// which is inclusionwise minimum. It is computed by processing a deba@2034: /// bfs from the source node \c source in the residual graph. deba@2037: /// \retval cut Write node bool map. deba@2034: template deba@2034: void minMinCut(CutMap& cut) const { deba@2034: deba@2034: typename Bfs deba@2034: ::template DefDistMap > deba@2034: ::template DefProcessedMap deba@2034: ::Create bfs(_resgraph); deba@2034: deba@2034: NullMap distMap; deba@2034: bfs.distMap(distMap); deba@2034: deba@2034: bfs.processedMap(cut); deba@2034: deba@2034: bfs.run(_source); deba@2034: } deba@2034: deba@2034: /// \brief Returns the inclusionwise minimum of the minimum value cuts. deba@2034: /// deba@2034: /// Sets \c cut to the characteristic vector of the minimum value cut deba@2034: /// which is inclusionwise minimum. It is computed by processing a deba@2034: /// bfs from the source node \c source in the residual graph. deba@2037: /// \retval cut Write node bool map. deba@2034: template deba@2034: void maxMinCut(CutMap& cut) const { deba@2034: deba@2034: typedef RevGraphAdaptor RevGraph; deba@2034: deba@2034: RevGraph revgraph(_resgraph); deba@2034: deba@2034: typename Bfs deba@2034: ::template DefDistMap > deba@2034: ::template DefPredMap > deba@2034: ::template DefProcessedMap > deba@2034: ::Create bfs(revgraph); deba@2034: deba@2034: NullMap distMap; deba@2034: bfs.distMap(distMap); deba@2034: deba@2034: NullMap predMap; deba@2034: bfs.predMap(predMap); deba@2034: deba@2034: NotWriteMap notcut(cut); deba@2034: bfs.processedMap(notcut); deba@2034: deba@2034: bfs.run(_target); deba@2034: } deba@2034: deba@2034: /// \brief Returns the source node. deba@2034: /// deba@2034: /// Returns the source node. deba@2034: /// deba@2034: Node source() const { deba@2034: return _source; deba@2034: } deba@2034: deba@2034: /// \brief Returns the target node. deba@2034: /// deba@2034: /// Returns the target node. deba@2034: /// deba@2034: Node target() const { deba@2034: return _target; deba@2034: } deba@2034: deba@2034: /// \brief Returns a reference to capacity map. deba@2034: /// deba@2034: /// Returns a reference to capacity map. deba@2034: /// deba@2034: const CapacityMap &capacityMap() const { deba@2034: return *_capacity; deba@2034: } deba@2034: deba@2034: /// \brief Returns a reference to flow map. deba@2034: /// deba@2034: /// Returns a reference to flow map. deba@2034: /// deba@2034: const FlowMap &flowMap() const { deba@2034: return *_flow; deba@2034: } deba@2034: deba@2036: /// \brief Returns the tolerance used by algorithm. deba@2036: /// deba@2036: /// Returns the tolerance used by algorithm. deba@2036: const Tolerance& tolerance() const { deba@2036: return tolerance; deba@2036: } deba@2036: deba@2034: private: deba@2034: deba@2034: const Graph& _graph; deba@2034: const CapacityMap& _capacity; deba@2034: FlowMap& _flow; deba@2034: Tolerance _tolerance; deba@2034: deba@2034: ResGraph _resgraph; deba@2034: Node _source, _target; deba@2034: Number _value; deba@2034: deba@2034: }; deba@2034: deba@2034: } deba@2034: deba@2034: #endif