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(0), _local_flow(false),
172 _potential(0), _local_potential(false), _res_cost(_cost)
174 // Removing non-zero lower bounds
175 _capacity = subMap(capacity, lower);
177 for (NodeIt n(_graph); n != INVALID; ++n) {
178 Supply s = supply[n];
179 for (InEdgeIt e(_graph, n); e != INVALID; ++e)
181 for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
183 sum += (_supply[n] = s);
185 _valid_supply = sum == 0;
188 /// \brief General constructor (without lower bounds).
190 /// General constructor (without lower bounds).
192 /// \param graph The directed graph the algorithm runs on.
193 /// \param capacity The capacities (upper bounds) of the edges.
194 /// \param cost The cost (length) values of the edges.
195 /// \param supply The supply values of the nodes (signed).
196 CycleCanceling( const Graph &graph,
197 const CapacityMap &capacity,
199 const SupplyMap &supply ) :
200 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
201 _supply(supply), _flow(0), _local_flow(false),
202 _potential(0), _local_potential(false), _res_cost(_cost)
204 // Checking the sum of supply values
206 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
207 _valid_supply = sum == 0;
210 /// \brief Simple constructor (with lower bounds).
212 /// Simple constructor (with lower bounds).
214 /// \param graph The directed graph the algorithm runs on.
215 /// \param lower The lower bounds of the edges.
216 /// \param capacity The capacities (upper bounds) of the edges.
217 /// \param cost The cost (length) values of the edges.
218 /// \param s The source node.
219 /// \param t The target node.
220 /// \param flow_value The required amount of flow from node \c s
221 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
222 CycleCanceling( const Graph &graph,
223 const LowerMap &lower,
224 const CapacityMap &capacity,
227 Supply flow_value ) :
228 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
229 _supply(graph), _flow(0), _local_flow(false),
230 _potential(0), _local_potential(false), _res_cost(_cost)
232 // Removing non-zero lower bounds
233 _capacity = subMap(capacity, lower);
234 for (NodeIt n(_graph); n != INVALID; ++n) {
236 if (n == s) sum = flow_value;
237 if (n == t) sum = -flow_value;
238 for (InEdgeIt e(_graph, n); e != INVALID; ++e)
240 for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
244 _valid_supply = true;
247 /// \brief Simple constructor (without lower bounds).
249 /// Simple constructor (without lower bounds).
251 /// \param graph The directed graph the algorithm runs on.
252 /// \param capacity The capacities (upper bounds) of the edges.
253 /// \param cost The cost (length) values of the edges.
254 /// \param s The source node.
255 /// \param t The target node.
256 /// \param flow_value The required amount of flow from node \c s
257 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
258 CycleCanceling( const Graph &graph,
259 const CapacityMap &capacity,
262 Supply flow_value ) :
263 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
264 _supply(graph, 0), _flow(0), _local_flow(false),
265 _potential(0), _local_potential(false), _res_cost(_cost)
267 _supply[s] = flow_value;
268 _supply[t] = -flow_value;
269 _valid_supply = true;
274 if (_local_flow) delete _flow;
275 if (_local_potential) delete _potential;
279 /// \brief Set the flow map.
281 /// Set the flow map.
283 /// \return \c (*this)
284 CycleCanceling& flowMap(FlowMap &map) {
293 /// \brief Set the potential map.
295 /// Set the potential map.
297 /// \return \c (*this)
298 CycleCanceling& potentialMap(PotentialMap &map) {
299 if (_local_potential) {
301 _local_potential = false;
307 /// \name Execution control
311 /// \brief Run the algorithm.
313 /// Run the algorithm.
315 /// \param min_mean_cc Set this parameter to \c true to run the
316 /// "Minimum Mean Cycle-Canceling" algorithm, which is strongly
317 /// polynomial, but rather slower in practice.
319 /// \return \c true if a feasible flow can be found.
320 bool run(bool min_mean_cc = false) {
321 return init() && start(min_mean_cc);
326 /// \name Query Functions
327 /// The result of the algorithm can be obtained using these
329 /// \ref lemon::CycleCanceling::run() "run()" must be called before
334 /// \brief Return a const reference to the edge map storing the
337 /// Return a const reference to the edge map storing the found flow.
339 /// \pre \ref run() must be called before using this function.
340 const FlowMap& flowMap() const {
344 /// \brief Return a const reference to the node map storing the
345 /// found potentials (the dual solution).
347 /// Return a const reference to the node map storing the found
348 /// potentials (the dual solution).
350 /// \pre \ref run() must be called before using this function.
351 const PotentialMap& potentialMap() const {
355 /// \brief Return the flow on the given edge.
357 /// Return the flow on the given edge.
359 /// \pre \ref run() must be called before using this function.
360 Capacity flow(const Edge& edge) const {
361 return (*_flow)[edge];
364 /// \brief Return the potential of the given node.
366 /// Return the potential of the given node.
368 /// \pre \ref run() must be called before using this function.
369 Cost potential(const Node& node) const {
370 return (*_potential)[node];
373 /// \brief Return the total cost of the found flow.
375 /// Return the total cost of the found flow. The complexity of the
376 /// function is \f$ O(e) \f$.
378 /// \pre \ref run() must be called before using this function.
379 Cost totalCost() const {
381 for (EdgeIt e(_graph); e != INVALID; ++e)
382 c += (*_flow)[e] * _cost[e];
390 /// Initialize the algorithm.
392 if (!_valid_supply) return false;
394 // Initializing flow and potential maps
396 _flow = new FlowMap(_graph);
400 _potential = new PotentialMap(_graph);
401 _local_potential = true;
404 _res_graph = new ResGraph(_graph, _capacity, *_flow);
406 // Finding a feasible flow using Circulation
407 Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
409 circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
411 return circulation.flowMap(*_flow).run();
414 bool start(bool min_mean_cc) {
420 // Handling non-zero lower bounds
422 for (EdgeIt e(_graph); e != INVALID; ++e)
423 (*_flow)[e] += (*_lower)[e];
428 /// \brief Execute the algorithm using \ref BellmanFord.
430 /// Execute the algorithm using the \ref BellmanFord
431 /// "Bellman-Ford" algorithm for negative cycle detection with
432 /// successively larger limit for the number of iterations.
434 typename BellmanFord<ResGraph, ResidualCostMap>::PredMap pred(*_res_graph);
435 typename ResGraph::template NodeMap<int> visited(*_res_graph);
436 std::vector<ResEdge> cycle;
437 int node_num = countNodes(_graph);
439 int length_bound = BF_FIRST_LIMIT;
440 bool optimal = false;
442 BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost);
446 bool cycle_found = false;
447 while (!cycle_found) {
448 int curr_iter_num = iter_num + length_bound <= node_num ?
449 length_bound : node_num - iter_num;
450 iter_num += curr_iter_num;
451 int real_iter_num = curr_iter_num;
452 for (int i = 0; i < curr_iter_num; ++i) {
453 if (bf.processNextWeakRound()) {
458 if (real_iter_num < curr_iter_num) {
459 // Optimal flow is found
461 // Setting node potentials
462 for (NodeIt n(_graph); n != INVALID; ++n)
463 (*_potential)[n] = bf.dist(n);
466 // Searching for node disjoint negative cycles
467 for (ResNodeIt n(*_res_graph); n != INVALID; ++n)
470 for (ResNodeIt n(*_res_graph); n != INVALID; ++n) {
471 if (visited[n] > 0) continue;
473 ResNode u = pred[n] == INVALID ?
474 INVALID : _res_graph->source(pred[n]);
475 while (u != INVALID && visited[u] == 0) {
477 u = pred[u] == INVALID ?
478 INVALID : _res_graph->source(pred[u]);
480 if (u != INVALID && visited[u] == id) {
481 // Finding the negative cycle
486 Capacity d = _res_graph->rescap(e);
487 while (_res_graph->source(e) != u) {
488 cycle.push_back(e = pred[_res_graph->source(e)]);
489 if (_res_graph->rescap(e) < d)
490 d = _res_graph->rescap(e);
493 // Augmenting along the cycle
494 for (int i = 0; i < int(cycle.size()); ++i)
495 _res_graph->augment(cycle[i], d);
501 length_bound = length_bound * BF_LIMIT_FACTOR / 100;
506 /// \brief Execute the algorithm using \ref MinMeanCycle.
508 /// Execute the algorithm using \ref MinMeanCycle for negative
510 void startMinMean() {
511 typedef Path<ResGraph> ResPath;
512 MinMeanCycle<ResGraph, ResidualCostMap> mmc(*_res_graph, _res_cost);
515 mmc.cyclePath(cycle).init();
516 if (mmc.findMinMean()) {
517 while (mmc.cycleLength() < 0) {
521 // Finding the largest flow amount that can be augmented
524 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) {
525 if (delta == 0 || _res_graph->rescap(e) < delta)
526 delta = _res_graph->rescap(e);
529 // Augmenting along the cycle
530 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e)
531 _res_graph->augment(e, delta);
533 // Finding the minimum cycle mean for the modified residual
536 if (!mmc.findMinMean()) break;
540 // Computing node potentials
541 BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost);
542 bf.init(0); bf.start();
543 for (NodeIt n(_graph); n != INVALID; ++n)
544 (*_potential)[n] = bf.dist(n);
547 }; //class CycleCanceling
553 #endif //LEMON_CYCLE_CANCELING_H