COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/edmonds_karp.h @ 2036:9d0c8a205e58

Last change on this file since 2036:9d0c8a205e58 was 2036:9d0c8a205e58, checked in by Balazs Dezso, 18 years ago

The algorithm does not change the capacity and the flow in the resgraph

File size: 10.9 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    template <typename CutMap>
256    void minCut(CutMap& cut) const {
257      minMinCut(cut);
258    }
259
260    /// \brief Returns the inclusionwise minimum of the minimum value cuts.
261    ///
262    /// Sets \c cut to the characteristic vector of the minimum value cut
263    /// which is inclusionwise minimum. It is computed by processing a
264    /// bfs from the source node \c source in the residual graph. 
265    template <typename CutMap>
266    void minMinCut(CutMap& cut) const {
267
268      typename Bfs<ResGraph>
269      ::template DefDistMap<NullMap<Node, int> >
270      ::template DefProcessedMap<CutMap>
271      ::Create bfs(_resgraph);
272
273      NullMap<Node, int> distMap;
274      bfs.distMap(distMap);
275
276      bfs.processedMap(cut);
277     
278      bfs.run(_source);
279    }
280
281    /// \brief Returns the inclusionwise minimum of the minimum value cuts.
282    ///
283    /// Sets \c cut to the characteristic vector of the minimum value cut
284    /// which is inclusionwise minimum. It is computed by processing a
285    /// bfs from the source node \c source in the residual graph. 
286    template <typename CutMap>
287    void maxMinCut(CutMap& cut) const {
288
289      typedef RevGraphAdaptor<const ResGraph> RevGraph;
290
291      RevGraph revgraph(_resgraph);
292
293      typename Bfs<RevGraph>
294      ::template DefDistMap<NullMap<Node, int> >
295      ::template DefPredMap<NullMap<Node, Edge> >
296      ::template DefProcessedMap<NotWriteMap<CutMap> >
297      ::Create bfs(revgraph);
298
299      NullMap<Node, int> distMap;
300      bfs.distMap(distMap);
301
302      NullMap<Node, Edge> predMap;
303      bfs.predMap(predMap);
304
305      NotWriteMap<CutMap> notcut(cut);
306      bfs.processedMap(notcut);
307     
308      bfs.run(_target);
309    }
310
311    /// \brief Returns the source node.
312    ///
313    /// Returns the source node.
314    ///
315    Node source() const {
316      return _source;
317    }
318
319    /// \brief Returns the target node.
320    ///
321    /// Returns the target node.
322    ///
323    Node target() const {
324      return _target;
325    }
326
327    /// \brief Returns a reference to capacity map.
328    ///
329    /// Returns a reference to capacity map.
330    ///
331    const CapacityMap &capacityMap() const {
332      return *_capacity;
333    }
334     
335    /// \brief Returns a reference to flow map.
336    ///
337    /// Returns a reference to flow map.
338    ///
339    const FlowMap &flowMap() const {
340      return *_flow;
341    }
342
343    /// \brief Returns the tolerance used by algorithm.
344    ///
345    /// Returns the tolerance used by algorithm.
346    const Tolerance& tolerance() const {
347      return tolerance;
348    }
349   
350  private:
351   
352    const Graph& _graph;
353    const CapacityMap& _capacity;
354    FlowMap& _flow;
355    Tolerance _tolerance;
356   
357    ResGraph _resgraph;
358    Node _source, _target;
359    Number _value;
360   
361  };
362
363}
364
365#endif
Note: See TracBrowser for help on using the repository browser.