3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
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_CYCLE_CANCELING_H
20 #define LEMON_CYCLE_CANCELING_H
22 /// \ingroup min_cost_flow
25 /// \brief Cycle-canceling algorithm for finding a minimum cost flow.
28 #include <lemon/graph_adaptor.h>
29 #include <lemon/path.h>
31 #include <lemon/circulation.h>
32 #include <lemon/bellman_ford.h>
33 #include <lemon/min_mean_cycle.h>
37 /// \addtogroup min_cost_flow
40 /// \brief Implementation of a cycle-canceling algorithm for
41 /// finding a minimum cost flow.
43 /// \ref CycleCanceling implements a cycle-canceling algorithm for
44 /// finding a minimum cost flow.
46 /// \tparam Graph The directed graph type the algorithm runs on.
47 /// \tparam LowerMap The type of the lower bound map.
48 /// \tparam CapacityMap The type of the capacity (upper bound) map.
49 /// \tparam CostMap The type of the cost (length) map.
50 /// \tparam SupplyMap The type of the supply map.
53 /// - Edge capacities and costs should be \e non-negative \e integers.
54 /// - Supply values should be \e signed \e integers.
55 /// - \c LowerMap::Value must be convertible to \c CapacityMap::Value.
56 /// - \c CapacityMap::Value and \c SupplyMap::Value must be
57 /// convertible to each other.
58 /// - All value types must be convertible to \c CostMap::Value, which
59 /// must be signed type.
61 /// \note By default the \ref BellmanFord "Bellman-Ford" algorithm is
62 /// used for negative cycle detection with limited iteration number.
63 /// However \ref CycleCanceling also provides the "Minimum Mean
64 /// Cycle-Canceling" algorithm, which is \e strongly \e polynomial,
65 /// but rather slower in practice.
66 /// To use this version of the algorithm, call \ref run() with \c true
69 /// \author Peter Kovacs
71 template < typename Graph,
72 typename LowerMap = typename Graph::template EdgeMap<int>,
73 typename CapacityMap = typename Graph::template EdgeMap<int>,
74 typename CostMap = typename Graph::template EdgeMap<int>,
75 typename SupplyMap = typename Graph::template NodeMap<int> >
78 GRAPH_TYPEDEFS(typename Graph);
80 typedef typename CapacityMap::Value Capacity;
81 typedef typename CostMap::Value Cost;
82 typedef typename SupplyMap::Value Supply;
83 typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap;
84 typedef typename Graph::template NodeMap<Supply> SupplyNodeMap;
86 typedef ResGraphAdaptor< const Graph, Capacity,
87 CapacityEdgeMap, CapacityEdgeMap > ResGraph;
88 typedef typename ResGraph::Node ResNode;
89 typedef typename ResGraph::NodeIt ResNodeIt;
90 typedef typename ResGraph::Edge ResEdge;
91 typedef typename ResGraph::EdgeIt ResEdgeIt;
95 /// The type of the flow map.
96 typedef typename Graph::template EdgeMap<Capacity> FlowMap;
100 /// \brief Map adaptor class for handling residual edge costs.
102 /// \ref ResidualCostMap is a map adaptor class for handling
103 /// residual edge costs.
104 class ResidualCostMap : public MapBase<ResEdge, Cost>
108 const CostMap &_cost_map;
113 ResidualCostMap(const CostMap &cost_map) : _cost_map(cost_map) {}
116 Cost operator[](const ResEdge &e) const {
117 return ResGraph::forward(e) ? _cost_map[e] : -_cost_map[e];
120 }; //class ResidualCostMap
124 // The maximum number of iterations for the first execution of the
125 // Bellman-Ford algorithm. It should be at least 2.
126 static const int BF_FIRST_LIMIT = 2;
127 // The iteration limit for the Bellman-Ford algorithm is multiplied
128 // by BF_ALPHA in every round.
129 static const double BF_ALPHA = 1.5;
133 // The directed graph the algorithm runs on
135 // The original lower bound map
136 const LowerMap *_lower;
137 // The modified capacity map
138 CapacityEdgeMap _capacity;
139 // The original cost map
140 const CostMap &_cost;
141 // The modified supply map
142 SupplyNodeMap _supply;
145 // Edge map of the current flow
148 // The residual graph
150 // The residual cost map
151 ResidualCostMap _res_cost;
155 /// \brief General constructor of the class (with lower bounds).
157 /// General constructor of the class (with lower bounds).
159 /// \param graph The directed graph the algorithm runs on.
160 /// \param lower The lower bounds of the edges.
161 /// \param capacity The capacities (upper bounds) of the edges.
162 /// \param cost The cost (length) values of the edges.
163 /// \param supply The supply values of the nodes (signed).
164 CycleCanceling( const Graph &graph,
165 const LowerMap &lower,
166 const CapacityMap &capacity,
168 const SupplyMap &supply ) :
169 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
170 _supply(graph), _flow(graph, 0),
171 _res_graph(graph, _capacity, _flow), _res_cost(_cost)
173 // Removing non-zero lower bounds
174 _capacity = subMap(capacity, lower);
176 for (NodeIt n(_graph); n != INVALID; ++n) {
177 Supply s = supply[n];
178 for (InEdgeIt e(_graph, n); e != INVALID; ++e)
180 for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
182 sum += (_supply[n] = s);
184 _valid_supply = sum == 0;
187 /// \brief General constructor of the class (without lower bounds).
189 /// General constructor of the class (without lower bounds).
191 /// \param graph The directed graph the algorithm runs on.
192 /// \param capacity The capacities (upper bounds) of the edges.
193 /// \param cost The cost (length) values of the edges.
194 /// \param supply The supply values of the nodes (signed).
195 CycleCanceling( const Graph &graph,
196 const CapacityMap &capacity,
198 const SupplyMap &supply ) :
199 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
200 _supply(supply), _flow(graph, 0),
201 _res_graph(graph, _capacity, _flow), _res_cost(_cost)
203 // Checking the sum of supply values
205 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
206 _valid_supply = sum == 0;
209 /// \brief Simple constructor of the class (with lower bounds).
211 /// Simple constructor of the class (with lower bounds).
213 /// \param graph The directed graph the algorithm runs on.
214 /// \param lower The lower bounds of the edges.
215 /// \param capacity The capacities (upper bounds) of the edges.
216 /// \param cost The cost (length) values of the edges.
217 /// \param s The source node.
218 /// \param t The target node.
219 /// \param flow_value The required amount of flow from node \c s
220 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
221 CycleCanceling( const Graph &graph,
222 const LowerMap &lower,
223 const CapacityMap &capacity,
226 Supply flow_value ) :
227 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
228 _supply(graph), _flow(graph, 0),
229 _res_graph(graph, _capacity, _flow), _res_cost(_cost)
231 // Removing non-zero lower bounds
232 _capacity = subMap(capacity, lower);
233 for (NodeIt n(_graph); n != INVALID; ++n) {
235 if (n == s) sum = flow_value;
236 if (n == t) sum = -flow_value;
237 for (InEdgeIt e(_graph, n); e != INVALID; ++e)
239 for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
243 _valid_supply = true;
246 /// \brief Simple constructor of the class (without lower bounds).
248 /// Simple constructor of the class (without lower bounds).
250 /// \param graph The directed graph the algorithm runs on.
251 /// \param capacity The capacities (upper bounds) of the edges.
252 /// \param cost The cost (length) values of the edges.
253 /// \param s The source node.
254 /// \param t The target node.
255 /// \param flow_value The required amount of flow from node \c s
256 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
257 CycleCanceling( const Graph &graph,
258 const CapacityMap &capacity,
261 Supply flow_value ) :
262 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
263 _supply(graph, 0), _flow(graph, 0),
264 _res_graph(graph, _capacity, _flow), _res_cost(_cost)
266 _supply[s] = flow_value;
267 _supply[t] = -flow_value;
268 _valid_supply = true;
271 /// \brief Runs the algorithm.
273 /// Runs the algorithm.
275 /// \param min_mean_cc Set this parameter to \c true to run the
276 /// "Minimum Mean Cycle-Canceling" algorithm, which is strongly
277 /// polynomial, but rather slower in practice.
279 /// \return \c true if a feasible flow can be found.
280 bool run(bool min_mean_cc = false) {
281 return init() && start(min_mean_cc);
284 /// \brief Returns a const reference to the edge map storing the
287 /// Returns a const reference to the edge map storing the found flow.
289 /// \pre \ref run() must be called before using this function.
290 const FlowMap& flowMap() const {
294 /// \brief Returns the total cost of the found flow.
296 /// Returns the total cost of the found flow. The complexity of the
297 /// function is \f$ O(e) \f$.
299 /// \pre \ref run() must be called before using this function.
300 Cost totalCost() const {
302 for (EdgeIt e(_graph); e != INVALID; ++e)
303 c += _flow[e] * _cost[e];
309 /// Initializes the algorithm.
311 if (!_valid_supply) return false;
313 // Finding a feasible flow using Circulation
314 Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
316 circulation( _graph, constMap<Edge>((Capacity)0), _capacity,
318 return circulation.flowMap(_flow).run();
321 bool start(bool min_mean_cc) {
323 return startMinMean();
328 /// \brief Executes the algorithm using \ref BellmanFord.
330 /// Executes the algorithm using the \ref BellmanFord
331 /// "Bellman-Ford" algorithm for negative cycle detection with
332 /// successively larger limit for the number of iterations.
334 typename BellmanFord<ResGraph, ResidualCostMap>::PredMap pred(_res_graph);
335 typename ResGraph::template NodeMap<int> visited(_res_graph);
336 std::vector<ResEdge> cycle;
337 int node_num = countNodes(_graph);
339 int length_bound = BF_FIRST_LIMIT;
340 bool optimal = false;
342 BellmanFord<ResGraph, ResidualCostMap> bf(_res_graph, _res_cost);
346 bool cycle_found = false;
347 while (!cycle_found) {
348 int curr_iter_num = iter_num + length_bound <= node_num ?
349 length_bound : node_num - iter_num;
350 iter_num += curr_iter_num;
351 int real_iter_num = curr_iter_num;
352 for (int i = 0; i < curr_iter_num; ++i) {
353 if (bf.processNextWeakRound()) {
358 if (real_iter_num < curr_iter_num) {
362 // Searching for node disjoint negative cycles
363 for (ResNodeIt n(_res_graph); n != INVALID; ++n)
366 for (ResNodeIt n(_res_graph); n != INVALID; ++n) {
367 if (visited[n] > 0) continue;
369 ResNode u = pred[n] == INVALID ?
370 INVALID : _res_graph.source(pred[n]);
371 while (u != INVALID && visited[u] == 0) {
373 u = pred[u] == INVALID ?
374 INVALID : _res_graph.source(pred[u]);
376 if (u != INVALID && visited[u] == id) {
377 // Finding the negative cycle
382 Capacity d = _res_graph.rescap(e);
383 while (_res_graph.source(e) != u) {
384 cycle.push_back(e = pred[_res_graph.source(e)]);
385 if (_res_graph.rescap(e) < d)
386 d = _res_graph.rescap(e);
389 // Augmenting along the cycle
390 for (int i = 0; i < int(cycle.size()); ++i)
391 _res_graph.augment(cycle[i], d);
397 length_bound = int(length_bound * BF_ALPHA);
401 // Handling non-zero lower bounds
403 for (EdgeIt e(_graph); e != INVALID; ++e)
404 _flow[e] += (*_lower)[e];
409 /// \brief Executes the algorithm using \ref MinMeanCycle.
411 /// Executes the algorithm using \ref MinMeanCycle for negative
413 bool startMinMean() {
414 typedef Path<ResGraph> ResPath;
415 MinMeanCycle<ResGraph, ResidualCostMap> mmc(_res_graph, _res_cost);
418 mmc.cyclePath(cycle).init();
419 if (mmc.findMinMean()) {
420 while (mmc.cycleLength() < 0) {
424 // Finding the largest flow amount that can be augmented
427 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) {
428 if (delta == 0 || _res_graph.rescap(e) < delta)
429 delta = _res_graph.rescap(e);
432 // Augmenting along the cycle
433 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e)
434 _res_graph.augment(e, delta);
436 // Finding the minimum cycle mean for the modified residual
439 if (!mmc.findMinMean()) break;
443 // Handling non-zero lower bounds
445 for (EdgeIt e(_graph); e != INVALID; ++e)
446 _flow[e] += (*_lower)[e];
451 }; //class CycleCanceling
457 #endif //LEMON_CYCLE_CANCELING_H