Improvements in CycleCanceling.
Main changes:
- Use function parameter instead of #define commands to select negative
cycle detection method.
- Change the name of private members to start with "_".
- Change the name of function parameters not to start with "_".
- Remove unnecessary documentation for private members.
- Doc improvements.
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_CAPACITY_SCALING_H
20 #define LEMON_CAPACITY_SCALING_H
22 /// \ingroup min_cost_flow
25 /// \brief The capacity scaling algorithm for finding a minimum cost flow.
27 #include <lemon/graph_adaptor.h>
28 #include <lemon/bin_heap.h>
33 /// \addtogroup min_cost_flow
36 /// \brief Implementation of the capacity scaling version of the
37 /// successive shortest path algorithm for finding a minimum cost
40 /// \ref CapacityScaling implements the capacity scaling version
41 /// of the successive shortest path algorithm for finding a minimum
44 /// \param Graph The directed graph type the algorithm runs on.
45 /// \param LowerMap The type of the lower bound map.
46 /// \param CapacityMap The type of the capacity (upper bound) map.
47 /// \param CostMap The type of the cost (length) map.
48 /// \param SupplyMap The type of the supply map.
51 /// - Edge capacities and costs should be non-negative integers.
52 /// However \c CostMap::Value should be signed type.
53 /// - Supply values should be signed integers.
54 /// - \c LowerMap::Value must be convertible to
55 /// \c CapacityMap::Value and \c CapacityMap::Value must be
56 /// convertible to \c SupplyMap::Value.
58 /// \author Peter Kovacs
60 template < typename Graph,
61 typename LowerMap = typename Graph::template EdgeMap<int>,
62 typename CapacityMap = LowerMap,
63 typename CostMap = typename Graph::template EdgeMap<int>,
64 typename SupplyMap = typename Graph::template NodeMap
65 <typename CapacityMap::Value> >
68 GRAPH_TYPEDEFS(typename Graph);
70 typedef typename LowerMap::Value Lower;
71 typedef typename CapacityMap::Value Capacity;
72 typedef typename CostMap::Value Cost;
73 typedef typename SupplyMap::Value Supply;
74 typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap;
75 typedef typename Graph::template NodeMap<Supply> SupplyNodeMap;
76 typedef typename Graph::template NodeMap<Edge> PredMap;
80 /// Type to enable or disable capacity scaling.
86 /// The type of the flow map.
87 typedef typename Graph::template EdgeMap<Capacity> FlowMap;
88 /// The type of the potential map.
89 typedef typename Graph::template NodeMap<Cost> PotentialMap;
93 /// \brief Special implementation of the \ref Dijkstra algorithm
94 /// for finding shortest paths in the residual network of the graph
95 /// with respect to the reduced edge costs and modifying the
96 /// node potentials according to the distance of the nodes.
97 class ResidualDijkstra
99 typedef typename Graph::template NodeMap<Cost> CostNodeMap;
100 typedef typename Graph::template NodeMap<Edge> PredMap;
102 typedef typename Graph::template NodeMap<int> HeapCrossRef;
103 typedef BinHeap<Cost, HeapCrossRef> Heap;
107 /// The directed graph the algorithm runs on.
112 /// The residual capacity map.
113 const CapacityEdgeMap &res_cap;
117 const SupplyNodeMap &excess;
119 /// The potential map.
120 PotentialMap &potential;
122 /// The distance map.
124 /// The map of predecessors edges.
126 /// The processed (i.e. permanently labeled) nodes.
127 std::vector<Node> proc_nodes;
131 /// The constructor of the class.
132 ResidualDijkstra( const Graph &_graph,
133 const FlowMap &_flow,
134 const CapacityEdgeMap &_res_cap,
135 const CostMap &_cost,
136 const SupplyMap &_excess,
137 PotentialMap &_potential,
139 graph(_graph), flow(_flow), res_cap(_res_cap), cost(_cost),
140 excess(_excess), potential(_potential), dist(_graph),
144 /// Runs the algorithm from the given source node.
145 Node run(Node s, Capacity delta) {
146 HeapCrossRef heap_cross_ref(graph, Heap::PRE_HEAP);
147 Heap heap(heap_cross_ref);
153 while (!heap.empty() && excess[heap.top()] > -delta) {
154 Node u = heap.top(), v;
155 Cost d = heap.prio() - potential[u], nd;
156 dist[u] = heap.prio();
158 proc_nodes.push_back(u);
160 // Traversing outgoing edges
161 for (OutEdgeIt e(graph, u); e != INVALID; ++e) {
162 if (res_cap[e] >= delta) {
164 switch(heap.state(v)) {
166 heap.push(v, d + cost[e] + potential[v]);
170 nd = d + cost[e] + potential[v];
172 heap.decrease(v, nd);
176 case Heap::POST_HEAP:
182 // Traversing incoming edges
183 for (InEdgeIt e(graph, u); e != INVALID; ++e) {
184 if (flow[e] >= delta) {
186 switch(heap.state(v)) {
188 heap.push(v, d - cost[e] + potential[v]);
192 nd = d - cost[e] + potential[v];
194 heap.decrease(v, nd);
198 case Heap::POST_HEAP:
204 if (heap.empty()) return INVALID;
206 // Updating potentials of processed nodes
208 Cost dt = heap.prio();
209 for (int i = 0; i < proc_nodes.size(); ++i)
210 potential[proc_nodes[i]] -= dist[proc_nodes[i]] - dt;
215 }; //class ResidualDijkstra
219 /// The directed graph the algorithm runs on.
221 /// The original lower bound map.
222 const LowerMap *lower;
223 /// The modified capacity map.
224 CapacityEdgeMap capacity;
227 /// The modified supply map.
228 SupplyNodeMap supply;
231 /// The edge map of the current flow.
233 /// The potential node map.
234 PotentialMap potential;
236 /// The residual capacity map.
237 CapacityEdgeMap res_cap;
239 SupplyNodeMap excess;
240 /// The excess nodes (i.e. the nodes with positive excess).
241 std::vector<Node> excess_nodes;
242 /// The deficit nodes (i.e. the nodes with negative excess).
243 std::vector<Node> deficit_nodes;
245 /// The scaling status (enabled or disabled).
247 /// The \c delta parameter used for capacity scaling.
249 /// The maximum number of phases.
252 /// \brief Implementation of the \ref Dijkstra algorithm for
253 /// finding augmenting shortest paths in the residual network.
254 ResidualDijkstra dijkstra;
255 /// The map of predecessors edges.
260 /// \brief General constructor of the class (with lower bounds).
262 /// General constructor of the class (with lower bounds).
264 /// \param _graph The directed graph the algorithm runs on.
265 /// \param _lower The lower bounds of the edges.
266 /// \param _capacity The capacities (upper bounds) of the edges.
267 /// \param _cost The cost (length) values of the edges.
268 /// \param _supply The supply values of the nodes (signed).
269 CapacityScaling( const Graph &_graph,
270 const LowerMap &_lower,
271 const CapacityMap &_capacity,
272 const CostMap &_cost,
273 const SupplyMap &_supply ) :
274 graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
275 supply(_graph), flow(_graph, 0), potential(_graph, 0),
276 res_cap(_graph), excess(_graph), pred(_graph),
277 dijkstra(graph, flow, res_cap, cost, excess, potential, pred)
279 // Removing non-zero lower bounds
280 capacity = subMap(_capacity, _lower);
283 for (NodeIt n(graph); n != INVALID; ++n) {
284 Supply s = _supply[n];
285 for (InEdgeIt e(graph, n); e != INVALID; ++e)
287 for (OutEdgeIt e(graph, n); e != INVALID; ++e)
292 valid_supply = sum == 0;
295 /// \brief General constructor of the class (without lower bounds).
297 /// General constructor of the class (without lower bounds).
299 /// \param _graph The directed graph the algorithm runs on.
300 /// \param _capacity The capacities (upper bounds) of the edges.
301 /// \param _cost The cost (length) values of the edges.
302 /// \param _supply The supply values of the nodes (signed).
303 CapacityScaling( const Graph &_graph,
304 const CapacityMap &_capacity,
305 const CostMap &_cost,
306 const SupplyMap &_supply ) :
307 graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
308 supply(_supply), flow(_graph, 0), potential(_graph, 0),
309 res_cap(_capacity), excess(_graph), pred(_graph),
310 dijkstra(graph, flow, res_cap, cost, excess, potential)
312 // Checking the sum of supply values
314 for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n];
315 valid_supply = sum == 0;
318 /// \brief Simple constructor of the class (with lower bounds).
320 /// Simple constructor of the class (with lower bounds).
322 /// \param _graph The directed graph the algorithm runs on.
323 /// \param _lower The lower bounds of the edges.
324 /// \param _capacity The capacities (upper bounds) of the edges.
325 /// \param _cost The cost (length) values of the edges.
326 /// \param _s The source node.
327 /// \param _t The target node.
328 /// \param _flow_value The required amount of flow from node \c _s
329 /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t).
330 CapacityScaling( const Graph &_graph,
331 const LowerMap &_lower,
332 const CapacityMap &_capacity,
333 const CostMap &_cost,
335 Supply _flow_value ) :
336 graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
337 supply(_graph), flow(_graph, 0), potential(_graph, 0),
338 res_cap(_graph), excess(_graph), pred(_graph),
339 dijkstra(graph, flow, res_cap, cost, excess, potential)
341 // Removing non-zero lower bounds
342 capacity = subMap(_capacity, _lower);
344 for (NodeIt n(graph); n != INVALID; ++n) {
346 if (n == _s) s = _flow_value;
347 if (n == _t) s = -_flow_value;
348 for (InEdgeIt e(graph, n); e != INVALID; ++e)
350 for (OutEdgeIt e(graph, n); e != INVALID; ++e)
357 /// \brief Simple constructor of the class (without lower bounds).
359 /// Simple constructor of the class (without lower bounds).
361 /// \param _graph The directed graph the algorithm runs on.
362 /// \param _capacity The capacities (upper bounds) of the edges.
363 /// \param _cost The cost (length) values of the edges.
364 /// \param _s The source node.
365 /// \param _t The target node.
366 /// \param _flow_value The required amount of flow from node \c _s
367 /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t).
368 CapacityScaling( const Graph &_graph,
369 const CapacityMap &_capacity,
370 const CostMap &_cost,
372 Supply _flow_value ) :
373 graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
374 supply(_graph, 0), flow(_graph, 0), potential(_graph, 0),
375 res_cap(_capacity), excess(_graph), pred(_graph),
376 dijkstra(graph, flow, res_cap, cost, excess, potential)
378 supply[_s] = _flow_value;
379 supply[_t] = -_flow_value;
383 /// \brief Runs the algorithm.
385 /// Runs the algorithm.
387 /// \param scaling_mode The scaling mode. In case of WITH_SCALING
388 /// capacity scaling is enabled in the algorithm (this is the
389 /// default) otherwise it is disabled.
390 /// If the maximum edge capacity and/or the amount of total supply
391 /// is small, the algorithm could be slightly faster without
394 /// \return \c true if a feasible flow can be found.
395 bool run(int scaling_mode = WITH_SCALING) {
396 return init(scaling_mode) && start();
399 /// \brief Returns a const reference to the flow map.
401 /// Returns a const reference to the flow map.
403 /// \pre \ref run() must be called before using this function.
404 const FlowMap& flowMap() const {
408 /// \brief Returns a const reference to the potential map (the dual
411 /// Returns a const reference to the potential map (the dual
414 /// \pre \ref run() must be called before using this function.
415 const PotentialMap& potentialMap() const {
419 /// \brief Returns the total cost of the found flow.
421 /// Returns the total cost of the found flow. The complexity of the
422 /// function is \f$ O(e) \f$.
424 /// \pre \ref run() must be called before using this function.
425 Cost totalCost() const {
427 for (EdgeIt e(graph); e != INVALID; ++e)
428 c += flow[e] * cost[e];
434 /// Initializes the algorithm.
435 bool init(int scaling_mode) {
436 if (!valid_supply) return false;
439 // Initilaizing delta value
440 if (scaling_mode == WITH_SCALING) {
442 Supply max_sup = 0, max_dem = 0;
443 for (NodeIt n(graph); n != INVALID; ++n) {
444 if ( supply[n] > max_sup) max_sup = supply[n];
445 if (-supply[n] > max_dem) max_dem = -supply[n];
447 if (max_dem < max_sup) max_sup = max_dem;
449 for (delta = 1; 2 * delta <= max_sup; delta *= 2)
458 /// Executes the algorithm.
461 return startWithScaling();
463 return startWithoutScaling();
466 /// \brief Executes the capacity scaling version of the successive
467 /// shortest path algorithm.
468 bool startWithScaling() {
469 // Processing capacity scaling phases
474 // Saturating all edges not satisfying the optimality condition
475 for (EdgeIt e(graph); e != INVALID; ++e) {
476 Node u = graph.source(e), v = graph.target(e);
477 Cost c = cost[e] - potential[u] + potential[v];
478 if (c < 0 && res_cap[e] >= delta) {
479 excess[u] -= res_cap[e];
480 excess[v] += res_cap[e];
481 flow[e] = capacity[e];
484 else if (c > 0 && flow[e] >= delta) {
485 excess[u] += flow[e];
486 excess[v] -= flow[e];
488 res_cap[e] = capacity[e];
492 // Finding excess nodes and deficit nodes
493 excess_nodes.clear();
494 deficit_nodes.clear();
495 for (NodeIt n(graph); n != INVALID; ++n) {
496 if (excess[n] >= delta) excess_nodes.push_back(n);
497 if (excess[n] <= -delta) deficit_nodes.push_back(n);
501 // Finding augmenting shortest paths
502 while (next_node < excess_nodes.size()) {
503 // Checking deficit nodes
505 bool delta_deficit = false;
506 for (int i = 0; i < deficit_nodes.size(); ++i) {
507 if (excess[deficit_nodes[i]] <= -delta) {
508 delta_deficit = true;
512 if (!delta_deficit) break;
516 s = excess_nodes[next_node];
517 if ((t = dijkstra.run(s, delta)) == INVALID) {
525 // Augmenting along a shortest path from s to t.
526 Capacity d = excess[s] < -excess[t] ? excess[s] : -excess[t];
530 while ((e = pred[u]) != INVALID) {
532 if (u == graph.target(e)) {
543 while ((e = pred[u]) != INVALID) {
544 if (u == graph.target(e)) {
557 if (excess[s] < delta) ++next_node;
560 if (delta == 1) break;
561 if (++phase_cnt > phase_num / 4) factor = 2;
562 delta = delta <= factor ? 1 : delta / factor;
565 // Handling non-zero lower bounds
567 for (EdgeIt e(graph); e != INVALID; ++e)
568 flow[e] += (*lower)[e];
573 /// \brief Executes the successive shortest path algorithm without
574 /// capacity scaling.
575 bool startWithoutScaling() {
576 // Finding excess nodes
577 for (NodeIt n(graph); n != INVALID; ++n)
578 if (excess[n] > 0) excess_nodes.push_back(n);
579 if (excess_nodes.size() == 0) return true;
582 // Finding shortest paths
584 while ( excess[excess_nodes[next_node]] > 0 ||
585 ++next_node < excess_nodes.size() )
588 s = excess_nodes[next_node];
589 if ((t = dijkstra.run(s, 1)) == INVALID)
592 // Augmenting along a shortest path from s to t
593 Capacity d = excess[s] < -excess[t] ? excess[s] : -excess[t];
596 while ((e = pred[u]) != INVALID) {
598 if (u == graph.target(e)) {
608 while ((e = pred[u]) != INVALID) {
609 if (u == graph.target(e)) {
623 // Handling non-zero lower bounds
625 for (EdgeIt e(graph); e != INVALID; ++e)
626 flow[e] += (*lower)[e];
631 }; //class CapacityScaling
637 #endif //LEMON_CAPACITY_SCALING_H