COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/edmonds_karp.h @ 2085:1970a93dfaa8

Last change on this file since 2085:1970a93dfaa8 was 2059:ebf3b2962554, checked in by Balazs Dezso, 18 years ago

Doc fix

File size: 11.0 KB
Line 
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
30namespace 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
Note: See TracBrowser for help on using the repository browser.