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 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.
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
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> >
63 /// \brief \ref Exception for the case when the source equals the target.
65 /// \ref Exception for the case when the source equals the target.
67 class InvalidArgument : public lemon::LogicError {
69 virtual const char* exceptionName() const {
70 return "lemon::EdmondsKarp::InvalidArgument";
75 /// \brief The graph type the algorithm runs on.
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;
86 typedef ResGraphAdaptor<Graph, Number, CapacityMap,
87 FlowMap, Tolerance> ResGraph;
91 typedef typename Graph::Node Node;
92 typedef typename Graph::Edge Edge;
94 typedef typename Graph::NodeIt NodeIt;
95 typedef typename Graph::EdgeIt EdgeIt;
96 typedef typename Graph::InEdgeIt InEdgeIt;
97 typedef typename Graph::OutEdgeIt OutEdgeIt;
101 /// \brief The constructor of the class.
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
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)
120 if (_source == _target) {
121 throw InvalidArgument();
125 /// \brief Initializes the algorithm
127 /// It sets the flow to empty flow.
129 for (EdgeIt it(_graph); it != INVALID; ++it) {
135 /// \brief Initializes the algorithm
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.
142 for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
145 for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
150 /// \brief Initializes the algorithm
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() {
159 for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
162 for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
165 for (NodeIt it(_graph); it != INVALID; ++it) {
166 if (it == _source || it == _target) continue;
168 for (OutEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
169 outFlow += _flow[jt];
172 for (InEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
175 if (_tolerance.different(outFlow, inFlow)) {
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;
186 /// \brief Augment the solution on an edge shortest path.
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
194 /// \return %False when the augmenting is not success so the
195 /// current flow is a feasible and optimal solution.
197 typename Bfs<ResGraph>
198 ::template DefDistMap<NullMap<Node, int> >
199 ::Create bfs(_resgraph);
201 NullMap<Node, int> distMap;
202 bfs.distMap(distMap);
205 bfs.addSource(_source);
208 if (!bfs.reached(_target)) {
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));
218 for (Node it = _target; it != _source; it = bfs.predNode(it)) {
219 _resgraph.augment(bfs.predEdge(it), min);
225 /// \brief Executes the algorithm
227 /// It runs augmenting phases until the optimal solution is reached.
232 /// \brief Gives back the current flow value.
234 /// Gives back the current flow _value.
235 Number flowValue() const {
239 /// \brief runs the algorithm.
241 /// It is just a shorthand for:
251 /// \brief Returns a minimum value cut.
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 {
261 /// \brief Returns the inclusionwise minimum of the minimum value cuts.
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 {
270 typename Bfs<ResGraph>
271 ::template DefDistMap<NullMap<Node, int> >
272 ::template DefProcessedMap<CutMap>
273 ::Create bfs(_resgraph);
275 NullMap<Node, int> distMap;
276 bfs.distMap(distMap);
278 bfs.processedMap(cut);
283 /// \brief Returns the inclusionwise minimum of the minimum value cuts.
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 {
292 typedef RevGraphAdaptor<const ResGraph> RevGraph;
294 RevGraph revgraph(_resgraph);
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);
302 NullMap<Node, int> distMap;
303 bfs.distMap(distMap);
305 NullMap<Node, Edge> predMap;
306 bfs.predMap(predMap);
308 NotWriteMap<CutMap> notcut(cut);
309 bfs.processedMap(notcut);
314 /// \brief Returns the source node.
316 /// Returns the source node.
318 Node source() const {
322 /// \brief Returns the target node.
324 /// Returns the target node.
326 Node target() const {
330 /// \brief Returns a reference to capacity map.
332 /// Returns a reference to capacity map.
334 const CapacityMap &capacityMap() const {
338 /// \brief Returns a reference to flow map.
340 /// Returns a reference to flow map.
342 const FlowMap &flowMap() const {
346 /// \brief Returns the tolerance used by algorithm.
348 /// Returns the tolerance used by algorithm.
349 const Tolerance& tolerance() const {
356 const CapacityMap& _capacity;
358 Tolerance _tolerance;
361 Node _source, _target;