Various improvements in NetworkSimplex.
- Faster variant of "Altering Candidate List" pivot rule using make_heap
instead of partial_sort.
- Doc improvements.
- Removing unecessary inline keywords.
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(capacity), _cost(cost),
171 _supply(supply), _flow(NULL), _local_flow(false),
172 _potential(NULL), _local_potential(false), _res_graph(NULL),
175 // Check the sum of supply values
177 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
178 _valid_supply = sum == 0;
180 // Remove non-zero lower bounds
181 for (EdgeIt e(_graph); e != INVALID; ++e) {
183 _capacity[e] -= lower[e];
184 _supply[_graph.source(e)] -= lower[e];
185 _supply[_graph.target(e)] += lower[e];
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(NULL), _local_flow(false),
204 _potential(NULL), _local_potential(false), _res_graph(NULL),
207 // Check the sum of supply values
209 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
210 _valid_supply = sum == 0;
213 /// \brief Simple constructor (with lower bounds).
215 /// Simple constructor (with lower bounds).
217 /// \param graph The directed graph the algorithm runs on.
218 /// \param lower The lower bounds of the edges.
219 /// \param capacity The capacities (upper bounds) of the edges.
220 /// \param cost The cost (length) values of the edges.
221 /// \param s The source node.
222 /// \param t The target node.
223 /// \param flow_value The required amount of flow from node \c s
224 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
225 CycleCanceling( const Graph &graph,
226 const LowerMap &lower,
227 const CapacityMap &capacity,
230 Supply flow_value ) :
231 _graph(graph), _lower(&lower), _capacity(capacity), _cost(cost),
232 _supply(graph, 0), _flow(NULL), _local_flow(false),
233 _potential(NULL), _local_potential(false), _res_graph(NULL),
236 // Remove non-zero lower bounds
237 _supply[s] = flow_value;
238 _supply[t] = -flow_value;
239 for (EdgeIt e(_graph); e != INVALID; ++e) {
241 _capacity[e] -= lower[e];
242 _supply[_graph.source(e)] -= lower[e];
243 _supply[_graph.target(e)] += lower[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(NULL), _local_flow(false),
267 _potential(NULL), _local_potential(false), _res_graph(NULL),
270 _supply[s] = flow_value;
271 _supply[t] = -flow_value;
272 _valid_supply = true;
277 if (_local_flow) delete _flow;
278 if (_local_potential) delete _potential;
282 /// \brief Set the flow map.
284 /// Set the flow map.
286 /// \return \c (*this)
287 CycleCanceling& flowMap(FlowMap &map) {
296 /// \brief Set the potential map.
298 /// Set the potential map.
300 /// \return \c (*this)
301 CycleCanceling& potentialMap(PotentialMap &map) {
302 if (_local_potential) {
304 _local_potential = false;
310 /// \name Execution control
314 /// \brief Run the algorithm.
316 /// Run the algorithm.
318 /// \param min_mean_cc Set this parameter to \c true to run the
319 /// "Minimum Mean Cycle-Canceling" algorithm, which is strongly
320 /// polynomial, but rather slower in practice.
322 /// \return \c true if a feasible flow can be found.
323 bool run(bool min_mean_cc = false) {
324 return init() && start(min_mean_cc);
329 /// \name Query Functions
330 /// The result of the algorithm can be obtained using these
332 /// \ref lemon::CycleCanceling::run() "run()" must be called before
337 /// \brief Return a const reference to the edge map storing the
340 /// Return 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 Return a const reference to the node map storing the
348 /// found potentials (the dual solution).
350 /// Return 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 Return the flow on the given edge.
360 /// Return the flow on the given 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 Return the potential of the given node.
369 /// Return the potential of the given 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 Return the total cost of the found flow.
378 /// Return 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 /// Initialize 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 Execute the algorithm using \ref BellmanFord.
433 /// Execute 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 = length_bound * BF_LIMIT_FACTOR / 100;
509 /// \brief Execute the algorithm using \ref MinMeanCycle.
511 /// Execute 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