3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
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.
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
19 #ifndef LEMON_EDMONDS_KARP_H
20 #define LEMON_EDMONDS_KARP_H
24 /// \brief Implementation of the Edmonds-Karp algorithm.
26 #include <lemon/graph_adaptor.h>
27 #include <lemon/tolerance.h>
28 #include <lemon/bfs.h>
33 /// \brief Edmonds-Karp algorithms class.
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
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.
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.
55 /// \author Balazs Dezso
57 template <typename _Graph, typename _Number,
58 typename _CapacityMap, typename _FlowMap, typename _Tolerance>
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> >
68 /// \brief \ref Exception for the case when the source equals the target.
70 /// \ref Exception for the case when the source equals the target.
72 class InvalidArgument : public lemon::LogicError {
74 virtual const char* exceptionName() const {
75 return "lemon::EdmondsKarp::InvalidArgument";
80 /// \brief The graph type the algorithm runs on.
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;
91 typedef ResGraphAdaptor<Graph, Number, CapacityMap,
92 FlowMap, Tolerance> ResGraph;
96 typedef typename Graph::Node Node;
97 typedef typename Graph::Edge Edge;
99 typedef typename Graph::NodeIt NodeIt;
100 typedef typename Graph::EdgeIt EdgeIt;
101 typedef typename Graph::InEdgeIt InEdgeIt;
102 typedef typename Graph::OutEdgeIt OutEdgeIt;
106 /// \brief The constructor of the class.
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)
122 if (_source == _target) {
123 throw InvalidArgument();
127 /// \brief Initializes the algorithm
129 /// It sets the flow to empty flow.
131 for (EdgeIt it(_graph); it != INVALID; ++it) {
137 /// \brief Initializes the algorithm
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.
144 for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
147 for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
152 /// \brief Initializes the algorithm
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() {
161 for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
164 for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
167 for (NodeIt it(_graph); it != INVALID; ++it) {
168 if (it == _source || it == _target) continue;
170 for (OutEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
171 outFlow += _flow[jt];
174 for (InEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
177 if (_tolerance.different(outFlow, inFlow)) {
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;
188 /// \brief Augment the solution on an edge shortest path.
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
196 /// \return %False when the augmenting is not success so the
197 /// current flow is a feasible and optimal solution.
199 typename Bfs<ResGraph>
200 ::template DefDistMap<NullMap<Node, int> >
201 ::Create bfs(_resgraph);
203 NullMap<Node, int> distMap;
204 bfs.distMap(distMap);
207 bfs.addSource(_source);
210 if (!bfs.reached(_target)) {
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));
220 for (Node it = _target; it != _source; it = bfs.predNode(it)) {
221 _resgraph.augment(bfs.predEdge(it), min);
227 /// \brief Executes the algorithm
229 /// It runs augmenting phases until the optimal solution is reached.
234 /// \brief Gives back the current flow value.
236 /// Gives back the current flow _value.
237 Number flowValue() const {
241 /// \brief runs the algorithm.
243 /// It is just a shorthand for:
254 /// \brief Returns a minimum value cut.
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 {
264 /// \brief Returns the inclusionwise minimum of the minimum value cuts.
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 {
273 typename Bfs<ResGraph>
274 ::template DefDistMap<NullMap<Node, int> >
275 ::template DefProcessedMap<CutMap>
276 ::Create bfs(_resgraph);
278 NullMap<Node, int> distMap;
279 bfs.distMap(distMap);
281 bfs.processedMap(cut);
286 /// \brief Returns the inclusionwise minimum of the minimum value cuts.
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 {
295 typedef RevGraphAdaptor<const ResGraph> RevGraph;
297 RevGraph revgraph(_resgraph);
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);
305 NullMap<Node, int> distMap;
306 bfs.distMap(distMap);
308 NullMap<Node, Edge> predMap;
309 bfs.predMap(predMap);
311 NotWriteMap<CutMap> notcut(cut);
312 bfs.processedMap(notcut);
317 /// \brief Returns the source node.
319 /// Returns the source node.
321 Node source() const {
325 /// \brief Returns the target node.
327 /// Returns the target node.
329 Node target() const {
333 /// \brief Returns a reference to capacity map.
335 /// Returns a reference to capacity map.
337 const CapacityMap &capacityMap() const {
341 /// \brief Returns a reference to flow map.
343 /// Returns a reference to flow map.
345 const FlowMap &flowMap() const {
349 /// \brief Returns the tolerance used by algorithm.
351 /// Returns the tolerance used by algorithm.
352 const Tolerance& tolerance() const {
359 const CapacityMap& _capacity;
361 Tolerance _tolerance;
364 Node _source, _target;