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 /// - The value types of the maps should be convertible to each other.
56 /// - \c CostMap::Value must be signed type.
58 /// \note By default the \ref BellmanFord "Bellman-Ford" algorithm is
59 /// used for negative cycle detection with limited iteration number.
60 /// However \ref CycleCanceling also provides the "Minimum Mean
61 /// Cycle-Canceling" algorithm, which is \e strongly \e polynomial,
62 /// but rather slower in practice.
63 /// To use this version of the algorithm, call \ref run() with \c true
66 /// \author Peter Kovacs
67 template < typename Graph,
68 typename LowerMap = typename Graph::template EdgeMap<int>,
69 typename CapacityMap = typename Graph::template EdgeMap<int>,
70 typename CostMap = typename Graph::template EdgeMap<int>,
71 typename SupplyMap = typename Graph::template NodeMap<int> >
74 GRAPH_TYPEDEFS(typename Graph);
76 typedef typename CapacityMap::Value Capacity;
77 typedef typename CostMap::Value Cost;
78 typedef typename SupplyMap::Value Supply;
79 typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap;
80 typedef typename Graph::template NodeMap<Supply> SupplyNodeMap;
82 typedef ResGraphAdaptor< const Graph, Capacity,
83 CapacityEdgeMap, CapacityEdgeMap > ResGraph;
84 typedef typename ResGraph::Node ResNode;
85 typedef typename ResGraph::NodeIt ResNodeIt;
86 typedef typename ResGraph::Edge ResEdge;
87 typedef typename ResGraph::EdgeIt ResEdgeIt;
91 /// The type of the flow map.
92 typedef typename Graph::template EdgeMap<Capacity> FlowMap;
93 /// The type of the potential map.
94 typedef typename Graph::template NodeMap<Cost> PotentialMap;
98 /// \brief Map adaptor class for handling residual edge costs.
100 /// Map adaptor class for handling residual edge costs.
101 class ResidualCostMap : public MapBase<ResEdge, Cost>
105 const CostMap &_cost_map;
110 ResidualCostMap(const CostMap &cost_map) : _cost_map(cost_map) {}
113 Cost operator[](const ResEdge &e) const {
114 return ResGraph::forward(e) ? _cost_map[e] : -_cost_map[e];
117 }; //class ResidualCostMap
121 // The maximum number of iterations for the first execution of the
122 // Bellman-Ford algorithm. It should be at least 2.
123 static const int BF_FIRST_LIMIT = 2;
124 // The iteration limit for the Bellman-Ford algorithm is multiplied
125 // by BF_LIMIT_FACTOR/100 in every round.
126 static const int BF_LIMIT_FACTOR = 150;
130 // The directed graph the algorithm runs on
132 // The original lower bound map
133 const LowerMap *_lower;
134 // The modified capacity map
135 CapacityEdgeMap _capacity;
136 // The original cost map
137 const CostMap &_cost;
138 // The modified supply map
139 SupplyNodeMap _supply;
142 // Edge map of the current flow
145 // Node map of the current potentials
146 PotentialMap *_potential;
147 bool _local_potential;
149 // The residual graph
150 ResGraph *_res_graph;
151 // The residual cost map
152 ResidualCostMap _res_cost;
156 /// \brief General constructor (with lower bounds).
158 /// General constructor (with lower bounds).
160 /// \param graph The directed graph the algorithm runs on.
161 /// \param lower The lower bounds of the edges.
162 /// \param capacity The capacities (upper bounds) of the edges.
163 /// \param cost The cost (length) values of the edges.
164 /// \param supply The supply values of the nodes (signed).
165 CycleCanceling( const Graph &graph,
166 const LowerMap &lower,
167 const CapacityMap &capacity,
169 const SupplyMap &supply ) :
170 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
171 _supply(graph), _flow(NULL), _local_flow(false),
172 _potential(NULL), _local_potential(false), _res_graph(NULL),
175 // Removing non-zero lower bounds
176 _capacity = subMap(capacity, lower);
178 for (NodeIt n(_graph); n != INVALID; ++n) {
179 Supply s = supply[n];
180 for (InEdgeIt e(_graph, n); e != INVALID; ++e)
182 for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
184 sum += (_supply[n] = s);
186 _valid_supply = sum == 0;
189 /// \brief General constructor (without lower bounds).
191 /// General constructor (without lower bounds).
193 /// \param graph The directed graph the algorithm runs on.
194 /// \param capacity The capacities (upper bounds) of the edges.
195 /// \param cost The cost (length) values of the edges.
196 /// \param supply The supply values of the nodes (signed).
197 CycleCanceling( const Graph &graph,
198 const CapacityMap &capacity,
200 const SupplyMap &supply ) :
201 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
202 _supply(supply), _flow(NULL), _local_flow(false),
203 _potential(NULL), _local_potential(false), _res_graph(NULL),
206 // Checking the sum of supply values
208 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
209 _valid_supply = sum == 0;
212 /// \brief Simple constructor (with lower bounds).
214 /// Simple constructor (with lower bounds).
216 /// \param graph The directed graph the algorithm runs on.
217 /// \param lower The lower bounds of the edges.
218 /// \param capacity The capacities (upper bounds) of the edges.
219 /// \param cost The cost (length) values of the edges.
220 /// \param s The source node.
221 /// \param t The target node.
222 /// \param flow_value The required amount of flow from node \c s
223 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
224 CycleCanceling( const Graph &graph,
225 const LowerMap &lower,
226 const CapacityMap &capacity,
229 Supply flow_value ) :
230 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
231 _supply(graph), _flow(NULL), _local_flow(false),
232 _potential(NULL), _local_potential(false), _res_graph(NULL),
235 // Removing non-zero lower bounds
236 _capacity = subMap(capacity, lower);
237 for (NodeIt n(_graph); n != INVALID; ++n) {
239 if (n == s) sum = flow_value;
240 if (n == t) sum = -flow_value;
241 for (InEdgeIt e(_graph, n); e != INVALID; ++e)
243 for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
247 _valid_supply = true;
250 /// \brief Simple constructor (without lower bounds).
252 /// Simple constructor (without lower bounds).
254 /// \param graph The directed graph the algorithm runs on.
255 /// \param capacity The capacities (upper bounds) of the edges.
256 /// \param cost The cost (length) values of the edges.
257 /// \param s The source node.
258 /// \param t The target node.
259 /// \param flow_value The required amount of flow from node \c s
260 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
261 CycleCanceling( const Graph &graph,
262 const CapacityMap &capacity,
265 Supply flow_value ) :
266 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
267 _supply(graph, 0), _flow(NULL), _local_flow(false),
268 _potential(NULL), _local_potential(false), _res_graph(NULL),
271 _supply[s] = flow_value;
272 _supply[t] = -flow_value;
273 _valid_supply = true;
278 if (_local_flow) delete _flow;
279 if (_local_potential) delete _potential;
283 /// \brief Set the flow map.
285 /// Set the flow map.
287 /// \return \c (*this)
288 CycleCanceling& flowMap(FlowMap &map) {
297 /// \brief Set the potential map.
299 /// Set the potential map.
301 /// \return \c (*this)
302 CycleCanceling& potentialMap(PotentialMap &map) {
303 if (_local_potential) {
305 _local_potential = false;
311 /// \name Execution control
315 /// \brief Run the algorithm.
317 /// Run the algorithm.
319 /// \param min_mean_cc Set this parameter to \c true to run the
320 /// "Minimum Mean Cycle-Canceling" algorithm, which is strongly
321 /// polynomial, but rather slower in practice.
323 /// \return \c true if a feasible flow can be found.
324 bool run(bool min_mean_cc = false) {
325 return init() && start(min_mean_cc);
330 /// \name Query Functions
331 /// The result of the algorithm can be obtained using these
333 /// \ref lemon::CycleCanceling::run() "run()" must be called before
338 /// \brief Return a const reference to the edge map storing the
341 /// Return a const reference to the edge map storing the found flow.
343 /// \pre \ref run() must be called before using this function.
344 const FlowMap& flowMap() const {
348 /// \brief Return a const reference to the node map storing the
349 /// found potentials (the dual solution).
351 /// Return a const reference to the node map storing the found
352 /// potentials (the dual solution).
354 /// \pre \ref run() must be called before using this function.
355 const PotentialMap& potentialMap() const {
359 /// \brief Return the flow on the given edge.
361 /// Return the flow on the given edge.
363 /// \pre \ref run() must be called before using this function.
364 Capacity flow(const Edge& edge) const {
365 return (*_flow)[edge];
368 /// \brief Return the potential of the given node.
370 /// Return the potential of the given node.
372 /// \pre \ref run() must be called before using this function.
373 Cost potential(const Node& node) const {
374 return (*_potential)[node];
377 /// \brief Return the total cost of the found flow.
379 /// Return the total cost of the found flow. The complexity of the
380 /// function is \f$ O(e) \f$.
382 /// \pre \ref run() must be called before using this function.
383 Cost totalCost() const {
385 for (EdgeIt e(_graph); e != INVALID; ++e)
386 c += (*_flow)[e] * _cost[e];
394 /// Initialize the algorithm.
396 if (!_valid_supply) return false;
398 // Initializing flow and potential maps
400 _flow = new FlowMap(_graph);
404 _potential = new PotentialMap(_graph);
405 _local_potential = true;
408 _res_graph = new ResGraph(_graph, _capacity, *_flow);
410 // Finding a feasible flow using Circulation
411 Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
413 circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
415 return circulation.flowMap(*_flow).run();
418 bool start(bool min_mean_cc) {
424 // Handling non-zero lower bounds
426 for (EdgeIt e(_graph); e != INVALID; ++e)
427 (*_flow)[e] += (*_lower)[e];
432 /// \brief Execute the algorithm using \ref BellmanFord.
434 /// Execute the algorithm using the \ref BellmanFord
435 /// "Bellman-Ford" algorithm for negative cycle detection with
436 /// successively larger limit for the number of iterations.
438 typename BellmanFord<ResGraph, ResidualCostMap>::PredMap pred(*_res_graph);
439 typename ResGraph::template NodeMap<int> visited(*_res_graph);
440 std::vector<ResEdge> cycle;
441 int node_num = countNodes(_graph);
443 int length_bound = BF_FIRST_LIMIT;
444 bool optimal = false;
446 BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost);
450 bool cycle_found = false;
451 while (!cycle_found) {
452 int curr_iter_num = iter_num + length_bound <= node_num ?
453 length_bound : node_num - iter_num;
454 iter_num += curr_iter_num;
455 int real_iter_num = curr_iter_num;
456 for (int i = 0; i < curr_iter_num; ++i) {
457 if (bf.processNextWeakRound()) {
462 if (real_iter_num < curr_iter_num) {
463 // Optimal flow is found
465 // Setting node potentials
466 for (NodeIt n(_graph); n != INVALID; ++n)
467 (*_potential)[n] = bf.dist(n);
470 // Searching for node disjoint negative cycles
471 for (ResNodeIt n(*_res_graph); n != INVALID; ++n)
474 for (ResNodeIt n(*_res_graph); n != INVALID; ++n) {
475 if (visited[n] > 0) continue;
477 ResNode u = pred[n] == INVALID ?
478 INVALID : _res_graph->source(pred[n]);
479 while (u != INVALID && visited[u] == 0) {
481 u = pred[u] == INVALID ?
482 INVALID : _res_graph->source(pred[u]);
484 if (u != INVALID && visited[u] == id) {
485 // Finding the negative cycle
490 Capacity d = _res_graph->rescap(e);
491 while (_res_graph->source(e) != u) {
492 cycle.push_back(e = pred[_res_graph->source(e)]);
493 if (_res_graph->rescap(e) < d)
494 d = _res_graph->rescap(e);
497 // Augmenting along the cycle
498 for (int i = 0; i < int(cycle.size()); ++i)
499 _res_graph->augment(cycle[i], d);
505 length_bound = length_bound * BF_LIMIT_FACTOR / 100;
510 /// \brief Execute the algorithm using \ref MinMeanCycle.
512 /// Execute the algorithm using \ref MinMeanCycle for negative
514 void startMinMean() {
515 typedef Path<ResGraph> ResPath;
516 MinMeanCycle<ResGraph, ResidualCostMap> mmc(*_res_graph, _res_cost);
519 mmc.cyclePath(cycle).init();
520 if (mmc.findMinMean()) {
521 while (mmc.cycleLength() < 0) {
525 // Finding the largest flow amount that can be augmented
528 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) {
529 if (delta == 0 || _res_graph->rescap(e) < delta)
530 delta = _res_graph->rescap(e);
533 // Augmenting along the cycle
534 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e)
535 _res_graph->augment(e, delta);
537 // Finding the minimum cycle mean for the modified residual
540 if (!mmc.findMinMean()) break;
544 // Computing node potentials
545 BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost);
546 bf.init(0); bf.start();
547 for (NodeIt n(_graph); n != INVALID; ++n)
548 (*_potential)[n] = bf.dist(n);
551 }; //class CycleCanceling
557 #endif //LEMON_CYCLE_CANCELING_H