COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/edmonds_karp.h @ 2037:32e4bebee616

Last change on this file since 2037:32e4bebee616 was 2037:32e4bebee616, checked in by Balazs Dezso, 18 years ago

Doxygen log corrections

doc of ResGraphAdaptor? has a bug in graph_adaptor.h

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