External flow and potential maps can be used in MinCostMaxFlow.
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
68 template < typename Graph,
69 typename LowerMap = typename Graph::template EdgeMap<int>,
70 typename CapacityMap = typename Graph::template EdgeMap<int>,
71 typename CostMap = typename Graph::template EdgeMap<int>,
72 typename SupplyMap = typename Graph::template NodeMap<int> >
75 GRAPH_TYPEDEFS(typename Graph);
77 typedef typename CapacityMap::Value Capacity;
78 typedef typename CostMap::Value Cost;
79 typedef typename SupplyMap::Value Supply;
80 typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap;
81 typedef typename Graph::template NodeMap<Supply> SupplyNodeMap;
83 typedef ResGraphAdaptor< const Graph, Capacity,
84 CapacityEdgeMap, CapacityEdgeMap > ResGraph;
85 typedef typename ResGraph::Node ResNode;
86 typedef typename ResGraph::NodeIt ResNodeIt;
87 typedef typename ResGraph::Edge ResEdge;
88 typedef typename ResGraph::EdgeIt ResEdgeIt;
92 /// The type of the flow map.
93 typedef typename Graph::template EdgeMap<Capacity> FlowMap;
94 /// The type of the potential map.
95 typedef typename Graph::template NodeMap<Cost> PotentialMap;
99 /// \brief Map adaptor class for handling residual edge costs.
101 /// \ref ResidualCostMap is a map adaptor class for handling
102 /// residual edge costs.
103 class ResidualCostMap : public MapBase<ResEdge, Cost>
107 const CostMap &_cost_map;
112 ResidualCostMap(const CostMap &cost_map) : _cost_map(cost_map) {}
115 Cost operator[](const ResEdge &e) const {
116 return ResGraph::forward(e) ? _cost_map[e] : -_cost_map[e];
119 }; //class ResidualCostMap
123 // The maximum number of iterations for the first execution of the
124 // Bellman-Ford algorithm. It should be at least 2.
125 static const int BF_FIRST_LIMIT = 2;
126 // The iteration limit for the Bellman-Ford algorithm is multiplied
127 // by BF_ALPHA in every round.
128 static const double BF_ALPHA = 1.5;
132 // The directed graph the algorithm runs on
134 // The original lower bound map
135 const LowerMap *_lower;
136 // The modified capacity map
137 CapacityEdgeMap _capacity;
138 // The original cost map
139 const CostMap &_cost;
140 // The modified supply map
141 SupplyNodeMap _supply;
144 // Edge map of the current flow
147 // Node map of the current potentials
148 PotentialMap *_potential;
149 bool _local_potential;
151 // The residual graph
152 ResGraph *_res_graph;
153 // The residual cost map
154 ResidualCostMap _res_cost;
158 /// \brief General constructor (with lower bounds).
160 /// General constructor (with lower bounds).
162 /// \param graph The directed graph the algorithm runs on.
163 /// \param lower The lower bounds of the edges.
164 /// \param capacity The capacities (upper bounds) of the edges.
165 /// \param cost The cost (length) values of the edges.
166 /// \param supply The supply values of the nodes (signed).
167 CycleCanceling( const Graph &graph,
168 const LowerMap &lower,
169 const CapacityMap &capacity,
171 const SupplyMap &supply ) :
172 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
173 _supply(graph), _flow(0), _local_flow(false),
174 _potential(0), _local_potential(false), _res_cost(_cost)
176 // Removing non-zero lower bounds
177 _capacity = subMap(capacity, lower);
179 for (NodeIt n(_graph); n != INVALID; ++n) {
180 Supply s = supply[n];
181 for (InEdgeIt e(_graph, n); e != INVALID; ++e)
183 for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
185 sum += (_supply[n] = s);
187 _valid_supply = sum == 0;
190 /// \brief General constructor (without lower bounds).
192 /// General constructor (without lower bounds).
194 /// \param graph The directed graph the algorithm runs on.
195 /// \param capacity The capacities (upper bounds) of the edges.
196 /// \param cost The cost (length) values of the edges.
197 /// \param supply The supply values of the nodes (signed).
198 CycleCanceling( const Graph &graph,
199 const CapacityMap &capacity,
201 const SupplyMap &supply ) :
202 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
203 _supply(supply), _flow(0), _local_flow(false),
204 _potential(0), _local_potential(false), _res_cost(_cost)
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(0), _local_flow(false),
232 _potential(0), _local_potential(false), _res_cost(_cost)
234 // Removing non-zero lower bounds
235 _capacity = subMap(capacity, lower);
236 for (NodeIt n(_graph); n != INVALID; ++n) {
238 if (n == s) sum = flow_value;
239 if (n == t) sum = -flow_value;
240 for (InEdgeIt e(_graph, n); e != INVALID; ++e)
242 for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
246 _valid_supply = true;
249 /// \brief Simple constructor (without lower bounds).
251 /// Simple constructor (without lower bounds).
253 /// \param graph The directed graph the algorithm runs on.
254 /// \param capacity The capacities (upper bounds) of the edges.
255 /// \param cost The cost (length) values of the edges.
256 /// \param s The source node.
257 /// \param t The target node.
258 /// \param flow_value The required amount of flow from node \c s
259 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
260 CycleCanceling( const Graph &graph,
261 const CapacityMap &capacity,
264 Supply flow_value ) :
265 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
266 _supply(graph, 0), _flow(0), _local_flow(false),
267 _potential(0), _local_potential(false), _res_cost(_cost)
269 _supply[s] = flow_value;
270 _supply[t] = -flow_value;
271 _valid_supply = true;
276 if (_local_flow) delete _flow;
277 if (_local_potential) delete _potential;
281 /// \brief Sets the flow map.
283 /// Sets the flow map.
285 /// \return \c (*this)
286 CycleCanceling& flowMap(FlowMap &map) {
295 /// \brief Sets the potential map.
297 /// Sets the potential map.
299 /// \return \c (*this)
300 CycleCanceling& potentialMap(PotentialMap &map) {
301 if (_local_potential) {
303 _local_potential = false;
309 /// \name Execution control
310 /// The only way to execute the algorithm is to call the run()
315 /// \brief Runs the algorithm.
317 /// Runs 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 /// \n run() must be called before using them.
337 /// \brief Returns a const reference to the edge map storing the
340 /// Returns a const reference to the edge map storing the found flow.
342 /// \pre \ref run() must be called before using this function.
343 const FlowMap& flowMap() const {
347 /// \brief Returns a const reference to the node map storing the
348 /// found potentials (the dual solution).
350 /// Returns a const reference to the node map storing the found
351 /// potentials (the dual solution).
353 /// \pre \ref run() must be called before using this function.
354 const PotentialMap& potentialMap() const {
358 /// \brief Returns the flow on the edge.
360 /// Returns the flow on the edge.
362 /// \pre \ref run() must be called before using this function.
363 Capacity flow(const Edge& edge) const {
364 return (*_flow)[edge];
367 /// \brief Returns the potential of the node.
369 /// Returns the potential of the node.
371 /// \pre \ref run() must be called before using this function.
372 Cost potential(const Node& node) const {
373 return (*_potential)[node];
376 /// \brief Returns the total cost of the found flow.
378 /// Returns the total cost of the found flow. The complexity of the
379 /// function is \f$ O(e) \f$.
381 /// \pre \ref run() must be called before using this function.
382 Cost totalCost() const {
384 for (EdgeIt e(_graph); e != INVALID; ++e)
385 c += (*_flow)[e] * _cost[e];
393 /// Initializes the algorithm.
395 if (!_valid_supply) return false;
397 // Initializing flow and potential maps
399 _flow = new FlowMap(_graph);
403 _potential = new PotentialMap(_graph);
404 _local_potential = true;
407 _res_graph = new ResGraph(_graph, _capacity, *_flow);
409 // Finding a feasible flow using Circulation
410 Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
412 circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
414 return circulation.flowMap(*_flow).run();
417 bool start(bool min_mean_cc) {
423 // Handling non-zero lower bounds
425 for (EdgeIt e(_graph); e != INVALID; ++e)
426 (*_flow)[e] += (*_lower)[e];
431 /// \brief Executes the algorithm using \ref BellmanFord.
433 /// Executes the algorithm using the \ref BellmanFord
434 /// "Bellman-Ford" algorithm for negative cycle detection with
435 /// successively larger limit for the number of iterations.
437 typename BellmanFord<ResGraph, ResidualCostMap>::PredMap pred(*_res_graph);
438 typename ResGraph::template NodeMap<int> visited(*_res_graph);
439 std::vector<ResEdge> cycle;
440 int node_num = countNodes(_graph);
442 int length_bound = BF_FIRST_LIMIT;
443 bool optimal = false;
445 BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost);
449 bool cycle_found = false;
450 while (!cycle_found) {
451 int curr_iter_num = iter_num + length_bound <= node_num ?
452 length_bound : node_num - iter_num;
453 iter_num += curr_iter_num;
454 int real_iter_num = curr_iter_num;
455 for (int i = 0; i < curr_iter_num; ++i) {
456 if (bf.processNextWeakRound()) {
461 if (real_iter_num < curr_iter_num) {
462 // Optimal flow is found
464 // Setting node potentials
465 for (NodeIt n(_graph); n != INVALID; ++n)
466 (*_potential)[n] = bf.dist(n);
469 // Searching for node disjoint negative cycles
470 for (ResNodeIt n(*_res_graph); n != INVALID; ++n)
473 for (ResNodeIt n(*_res_graph); n != INVALID; ++n) {
474 if (visited[n] > 0) continue;
476 ResNode u = pred[n] == INVALID ?
477 INVALID : _res_graph->source(pred[n]);
478 while (u != INVALID && visited[u] == 0) {
480 u = pred[u] == INVALID ?
481 INVALID : _res_graph->source(pred[u]);
483 if (u != INVALID && visited[u] == id) {
484 // Finding the negative cycle
489 Capacity d = _res_graph->rescap(e);
490 while (_res_graph->source(e) != u) {
491 cycle.push_back(e = pred[_res_graph->source(e)]);
492 if (_res_graph->rescap(e) < d)
493 d = _res_graph->rescap(e);
496 // Augmenting along the cycle
497 for (int i = 0; i < int(cycle.size()); ++i)
498 _res_graph->augment(cycle[i], d);
504 length_bound = int(length_bound * BF_ALPHA);
509 /// \brief Executes the algorithm using \ref MinMeanCycle.
511 /// Executes the algorithm using \ref MinMeanCycle for negative
513 void startMinMean() {
514 typedef Path<ResGraph> ResPath;
515 MinMeanCycle<ResGraph, ResidualCostMap> mmc(*_res_graph, _res_cost);
518 mmc.cyclePath(cycle).init();
519 if (mmc.findMinMean()) {
520 while (mmc.cycleLength() < 0) {
524 // Finding the largest flow amount that can be augmented
527 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) {
528 if (delta == 0 || _res_graph->rescap(e) < delta)
529 delta = _res_graph->rescap(e);
532 // Augmenting along the cycle
533 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e)
534 _res_graph->augment(e, delta);
536 // Finding the minimum cycle mean for the modified residual
539 if (!mmc.findMinMean()) break;
543 // Computing node potentials
544 BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost);
545 bf.init(0); bf.start();
546 for (NodeIt n(_graph); n != INVALID; ++n)
547 (*_potential)[n] = bf.dist(n);
550 }; //class CycleCanceling
556 #endif //LEMON_CYCLE_CANCELING_H