3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
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
28 #include <lemon/graph_adaptor.h>
29 #include <lemon/bin_heap.h>
34 /// \addtogroup min_cost_flow
37 /// \brief Implementation of the capacity scaling version of the
38 /// successive shortest path algorithm for finding a minimum cost
41 /// \ref CapacityScaling implements the capacity scaling version
42 /// of the successive shortest path algorithm for finding a minimum
45 /// \param Graph The directed graph type the algorithm runs on.
46 /// \param LowerMap The type of the lower bound map.
47 /// \param CapacityMap The type of the capacity (upper bound) map.
48 /// \param CostMap The type of the cost (length) map.
49 /// \param SupplyMap The type of the supply map.
52 /// - Edge capacities and costs should be nonnegative integers.
53 /// However \c CostMap::Value should be signed type.
54 /// - Supply values should be signed integers.
55 /// - \c LowerMap::Value must be convertible to
56 /// \c CapacityMap::Value and \c CapacityMap::Value must be
57 /// convertible to \c SupplyMap::Value.
59 /// \author Peter Kovacs
61 template < typename Graph,
62 typename LowerMap = typename Graph::template EdgeMap<int>,
63 typename CapacityMap = LowerMap,
64 typename CostMap = typename Graph::template EdgeMap<int>,
65 typename SupplyMap = typename Graph::template NodeMap
66 <typename CapacityMap::Value> >
69 typedef typename Graph::Node Node;
70 typedef typename Graph::NodeIt NodeIt;
71 typedef typename Graph::Edge Edge;
72 typedef typename Graph::EdgeIt EdgeIt;
73 typedef typename Graph::InEdgeIt InEdgeIt;
74 typedef typename Graph::OutEdgeIt OutEdgeIt;
76 typedef typename LowerMap::Value Lower;
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> CapacityRefMap;
81 typedef typename Graph::template NodeMap<Supply> SupplyRefMap;
82 typedef typename Graph::template NodeMap<Edge> PredMap;
86 /// \brief Type to enable or disable capacity scaling.
92 /// \brief The type of the flow map.
93 typedef CapacityRefMap FlowMap;
94 /// \brief The type of the potential map.
95 typedef typename Graph::template NodeMap<Cost> PotentialMap;
99 /// \brief Special implementation of the \ref Dijkstra algorithm
100 /// for finding shortest paths in the residual network of the graph
101 /// with respect to the reduced edge costs and modifying the
102 /// node potentials according to the distance of the nodes.
103 class ResidualDijkstra
105 typedef typename Graph::template NodeMap<Cost> CostNodeMap;
106 typedef typename Graph::template NodeMap<Edge> PredMap;
108 typedef typename Graph::template NodeMap<int> HeapCrossRef;
109 typedef BinHeap<Cost, HeapCrossRef> Heap;
113 /// \brief The directed graph the algorithm runs on.
116 /// \brief The flow map.
118 /// \brief The residual capacity map.
119 const CapacityRefMap &res_cap;
120 /// \brief The cost map.
122 /// \brief The excess map.
123 const SupplyRefMap &excess;
125 /// \brief The potential map.
126 PotentialMap &potential;
128 /// \brief The distance map.
130 /// \brief The map of predecessors edges.
132 /// \brief The processed (i.e. permanently labeled) nodes.
133 std::vector<Node> proc_nodes;
137 /// \brief The constructor of the class.
138 ResidualDijkstra( const Graph &_graph,
139 const FlowMap &_flow,
140 const CapacityRefMap &_res_cap,
141 const CostMap &_cost,
142 const SupplyMap &_excess,
143 PotentialMap &_potential,
145 graph(_graph), flow(_flow), res_cap(_res_cap), cost(_cost),
146 excess(_excess), potential(_potential), dist(_graph),
150 /// \brief Runs the algorithm from the given source node.
151 Node run(Node s, Capacity delta) {
152 HeapCrossRef heap_cross_ref(graph, Heap::PRE_HEAP);
153 Heap heap(heap_cross_ref);
159 while (!heap.empty() && excess[heap.top()] > -delta) {
160 Node u = heap.top(), v;
161 Cost d = heap.prio() - potential[u], nd;
162 dist[u] = heap.prio();
164 proc_nodes.push_back(u);
166 // Traversing outgoing edges
167 for (OutEdgeIt e(graph, u); e != INVALID; ++e) {
168 if (res_cap[e] >= delta) {
170 switch(heap.state(v)) {
172 heap.push(v, d + cost[e] + potential[v]);
176 nd = d + cost[e] + potential[v];
178 heap.decrease(v, nd);
182 case Heap::POST_HEAP:
188 // Traversing incoming edges
189 for (InEdgeIt e(graph, u); e != INVALID; ++e) {
190 if (flow[e] >= delta) {
192 switch(heap.state(v)) {
194 heap.push(v, d - cost[e] + potential[v]);
198 nd = d - cost[e] + potential[v];
200 heap.decrease(v, nd);
204 case Heap::POST_HEAP:
210 if (heap.empty()) return INVALID;
212 // Updating potentials of processed nodes
214 Cost dt = heap.prio();
215 for (int i = 0; i < proc_nodes.size(); ++i)
216 potential[proc_nodes[i]] -= dist[proc_nodes[i]] - dt;
221 }; //class ResidualDijkstra
225 /// \brief The directed graph the algorithm runs on.
227 /// \brief The original lower bound map.
228 const LowerMap *lower;
229 /// \brief The modified capacity map.
230 CapacityRefMap capacity;
231 /// \brief The cost map.
233 /// \brief The modified supply map.
235 /// \brief The sum of supply values equals zero.
238 /// \brief The edge map of the current flow.
240 /// \brief The potential node map.
241 PotentialMap potential;
243 /// \brief The residual capacity map.
244 CapacityRefMap res_cap;
245 /// \brief The excess map.
247 /// \brief The excess nodes (i.e. nodes with positive excess).
248 std::vector<Node> excess_nodes;
249 /// \brief The index of the next excess node.
252 /// \brief The scaling status (enabled or disabled).
254 /// \brief The delta parameter used for capacity scaling.
256 /// \brief The maximum number of phases.
258 /// \brief The deficit nodes.
259 std::vector<Node> deficit_nodes;
261 /// \brief Implementation of the \ref Dijkstra algorithm for
262 /// finding augmenting shortest paths in the residual network.
263 ResidualDijkstra dijkstra;
264 /// \brief The map of predecessors edges.
269 /// \brief General constructor of the class (with lower bounds).
271 /// General constructor of the class (with lower bounds).
273 /// \param _graph The directed graph the algorithm runs on.
274 /// \param _lower The lower bounds of the edges.
275 /// \param _capacity The capacities (upper bounds) of the edges.
276 /// \param _cost The cost (length) values of the edges.
277 /// \param _supply The supply values of the nodes (signed).
278 CapacityScaling( const Graph &_graph,
279 const LowerMap &_lower,
280 const CapacityMap &_capacity,
281 const CostMap &_cost,
282 const SupplyMap &_supply ) :
283 graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
284 supply(_graph), flow(_graph, 0), potential(_graph, 0),
285 res_cap(_graph), excess(_graph), pred(_graph),
286 dijkstra(graph, flow, res_cap, cost, excess, potential, pred)
288 // Removing nonzero lower bounds
289 capacity = subMap(_capacity, _lower);
292 for (NodeIt n(graph); n != INVALID; ++n) {
293 Supply s = _supply[n];
294 for (InEdgeIt e(graph, n); e != INVALID; ++e)
296 for (OutEdgeIt e(graph, n); e != INVALID; ++e)
301 valid_supply = sum == 0;
304 /// \brief General constructor of the class (without lower bounds).
306 /// General constructor of the class (without lower bounds).
308 /// \param _graph The directed graph the algorithm runs on.
309 /// \param _capacity The capacities (upper bounds) of the edges.
310 /// \param _cost The cost (length) values of the edges.
311 /// \param _supply The supply values of the nodes (signed).
312 CapacityScaling( const Graph &_graph,
313 const CapacityMap &_capacity,
314 const CostMap &_cost,
315 const SupplyMap &_supply ) :
316 graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
317 supply(_supply), flow(_graph, 0), potential(_graph, 0),
318 res_cap(_capacity), excess(_graph), pred(_graph),
319 dijkstra(graph, flow, res_cap, cost, excess, potential)
321 // Checking the sum of supply values
323 for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n];
324 valid_supply = sum == 0;
327 /// \brief Simple constructor of the class (with lower bounds).
329 /// Simple constructor of the class (with lower bounds).
331 /// \param _graph The directed graph the algorithm runs on.
332 /// \param _lower The lower bounds of the edges.
333 /// \param _capacity The capacities (upper bounds) of the edges.
334 /// \param _cost The cost (length) values of the edges.
335 /// \param _s The source node.
336 /// \param _t The target node.
337 /// \param _flow_value The required amount of flow from node \c _s
338 /// to node \c _t (i.e. the supply of \c _s and the demand of
340 CapacityScaling( const Graph &_graph,
341 const LowerMap &_lower,
342 const CapacityMap &_capacity,
343 const CostMap &_cost,
345 Supply _flow_value ) :
346 graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
347 supply(_graph), flow(_graph, 0), potential(_graph, 0),
348 res_cap(_graph), excess(_graph), pred(_graph),
349 dijkstra(graph, flow, res_cap, cost, excess, potential)
351 // Removing nonzero lower bounds
352 capacity = subMap(_capacity, _lower);
354 for (NodeIt n(graph); n != INVALID; ++n) {
356 if (n == _s) s = _flow_value;
357 if (n == _t) s = -_flow_value;
358 for (InEdgeIt e(graph, n); e != INVALID; ++e)
360 for (OutEdgeIt e(graph, n); e != INVALID; ++e)
367 /// \brief Simple constructor of the class (without lower bounds).
369 /// Simple constructor of the class (without lower bounds).
371 /// \param _graph The directed graph the algorithm runs on.
372 /// \param _capacity The capacities (upper bounds) of the edges.
373 /// \param _cost The cost (length) values of the edges.
374 /// \param _s The source node.
375 /// \param _t The target node.
376 /// \param _flow_value The required amount of flow from node \c _s
377 /// to node \c _t (i.e. the supply of \c _s and the demand of
379 CapacityScaling( const Graph &_graph,
380 const CapacityMap &_capacity,
381 const CostMap &_cost,
383 Supply _flow_value ) :
384 graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
385 supply(_graph, 0), flow(_graph, 0), potential(_graph, 0),
386 res_cap(_capacity), excess(_graph), pred(_graph),
387 dijkstra(graph, flow, res_cap, cost, excess, potential)
389 supply[_s] = _flow_value;
390 supply[_t] = -_flow_value;
394 /// \brief Returns a const reference to the flow map.
396 /// Returns a const reference to the flow map.
398 /// \pre \ref run() must be called before using this function.
399 const FlowMap& flowMap() const {
403 /// \brief Returns a const reference to the potential map (the dual
406 /// Returns a const reference to the potential map (the dual
409 /// \pre \ref run() must be called before using this function.
410 const PotentialMap& potentialMap() const {
414 /// \brief Returns the total cost of the found flow.
416 /// Returns the total cost of the found flow. The complexity of the
417 /// function is \f$ O(e) \f$.
419 /// \pre \ref run() must be called before using this function.
420 Cost totalCost() const {
422 for (EdgeIt e(graph); e != INVALID; ++e)
423 c += flow[e] * cost[e];
427 /// \brief Runs the algorithm.
429 /// Runs the algorithm.
431 /// \param scaling_mode The scaling mode. In case of WITH_SCALING
432 /// capacity scaling is enabled in the algorithm (this is the
433 /// default value) otherwise it is disabled.
434 /// If the maximum edge capacity and/or the amount of total supply
435 /// is small, the algorithm could be faster without scaling.
437 /// \return \c true if a feasible flow can be found.
438 bool run(int scaling_mode = WITH_SCALING) {
439 return init(scaling_mode) && start();
444 /// \brief Initializes the algorithm.
445 bool init(int scaling_mode) {
446 if (!valid_supply) return false;
449 // Initilaizing delta value
450 if (scaling_mode == WITH_SCALING) {
452 Supply max_sup = 0, max_dem = 0;
453 for (NodeIt n(graph); n != INVALID; ++n) {
454 if ( supply[n] > max_sup) max_sup = supply[n];
455 if (-supply[n] > max_dem) max_dem = -supply[n];
457 if (max_dem < max_sup) max_sup = max_dem;
459 for (delta = 1; 2 * delta <= max_sup; delta *= 2)
468 /// \brief Executes the algorithm.
471 return startWithScaling();
473 return startWithoutScaling();
476 /// \brief Executes the capacity scaling version of the successive
477 /// shortest path algorithm.
478 bool startWithScaling() {
479 // Processing capacity scaling phases
484 // Saturating all edges not satisfying the optimality condition
485 for (EdgeIt e(graph); e != INVALID; ++e) {
486 Node u = graph.source(e), v = graph.target(e);
487 Cost c = cost[e] - potential[u] + potential[v];
488 if (c < 0 && res_cap[e] >= delta) {
489 excess[u] -= res_cap[e];
490 excess[v] += res_cap[e];
491 flow[e] = capacity[e];
494 else if (c > 0 && flow[e] >= delta) {
495 excess[u] += flow[e];
496 excess[v] -= flow[e];
498 res_cap[e] = capacity[e];
502 // Finding excess nodes and deficit nodes
503 excess_nodes.clear();
504 deficit_nodes.clear();
505 for (NodeIt n(graph); n != INVALID; ++n) {
506 if (excess[n] >= delta) excess_nodes.push_back(n);
507 if (excess[n] <= -delta) deficit_nodes.push_back(n);
511 // Finding augmenting shortest paths
512 while (next_node < excess_nodes.size()) {
513 // Checking deficit nodes
515 bool delta_deficit = false;
516 for (int i = 0; i < deficit_nodes.size(); ++i) {
517 if (excess[deficit_nodes[i]] <= -delta) {
518 delta_deficit = true;
522 if (!delta_deficit) break;
526 s = excess_nodes[next_node];
527 if ((t = dijkstra.run(s, delta)) == INVALID) {
535 // Augmenting along a shortest path from s to t.
536 Capacity d = excess[s] < -excess[t] ? excess[s] : -excess[t];
540 while ((e = pred[u]) != INVALID) {
542 if (u == graph.target(e)) {
553 while ((e = pred[u]) != INVALID) {
554 if (u == graph.target(e)) {
567 if (excess[s] < delta) ++next_node;
570 if (delta == 1) break;
571 if (++phase_cnt > phase_num / 4) factor = 2;
572 delta = delta <= factor ? 1 : delta / factor;
575 // Handling nonzero lower bounds
577 for (EdgeIt e(graph); e != INVALID; ++e)
578 flow[e] += (*lower)[e];
583 /// \brief Executes the successive shortest path algorithm without
584 /// capacity scaling.
585 bool startWithoutScaling() {
586 // Finding excess nodes
587 for (NodeIt n(graph); n != INVALID; ++n) {
588 if (excess[n] > 0) excess_nodes.push_back(n);
590 if (excess_nodes.size() == 0) return true;
593 // Finding shortest paths
595 while ( excess[excess_nodes[next_node]] > 0 ||
596 ++next_node < excess_nodes.size() )
599 s = excess_nodes[next_node];
600 if ((t = dijkstra.run(s, 1)) == INVALID)
603 // Augmenting along a shortest path from s to t
604 Capacity d = excess[s] < -excess[t] ? excess[s] : -excess[t];
607 while ((e = pred[u]) != INVALID) {
609 if (u == graph.target(e)) {
619 while ((e = pred[u]) != INVALID) {
620 if (u == graph.target(e)) {
634 // Handling nonzero lower bounds
636 for (EdgeIt e(graph); e != INVALID; ++e)
637 flow[e] += (*lower)[e];
642 }; //class CapacityScaling
648 #endif //LEMON_CAPACITY_SCALING_H