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
29 #include <lemon/dijkstra.h>
30 #include <lemon/graph_adaptor.h>
35 #define SCALING_FACTOR 2
38 //#define _DEBUG_ITER_
42 /// \addtogroup min_cost_flow
45 /// \brief Implementation of the capacity scaling version of the
46 /// successive shortest path algorithm for finding a minimum cost flow.
48 /// \ref lemon::CapacityScaling "CapacityScaling" implements a
49 /// capacity scaling algorithm for finding a minimum cost flow.
51 /// \param Graph The directed graph type the algorithm runs on.
52 /// \param LowerMap The type of the lower bound map.
53 /// \param CapacityMap The type of the capacity (upper bound) map.
54 /// \param CostMap The type of the cost (length) map.
55 /// \param SupplyMap The type of the supply map.
58 /// - Edge capacities and costs should be nonnegative integers.
59 /// However \c CostMap::Value should be signed type.
60 /// - Supply values should be integers.
61 /// - \c LowerMap::Value must be convertible to
62 /// \c CapacityMap::Value and \c CapacityMap::Value must be
63 /// convertible to \c SupplyMap::Value.
65 /// \author Peter Kovacs
67 template < typename Graph,
68 typename LowerMap = typename Graph::template EdgeMap<int>,
69 typename CapacityMap = LowerMap,
70 typename CostMap = typename Graph::template EdgeMap<int>,
71 typename SupplyMap = typename Graph::template NodeMap
72 <typename CapacityMap::Value> >
75 typedef typename Graph::Node Node;
76 typedef typename Graph::NodeIt NodeIt;
77 typedef typename Graph::Edge Edge;
78 typedef typename Graph::EdgeIt EdgeIt;
79 typedef typename Graph::InEdgeIt InEdgeIt;
80 typedef typename Graph::OutEdgeIt OutEdgeIt;
82 typedef typename LowerMap::Value Lower;
83 typedef typename CapacityMap::Value Capacity;
84 typedef typename CostMap::Value Cost;
85 typedef typename SupplyMap::Value Supply;
86 typedef typename Graph::template EdgeMap<Capacity> CapacityRefMap;
87 typedef typename Graph::template NodeMap<Supply> SupplyRefMap;
89 typedef ResGraphAdaptor< const Graph, Capacity,
90 CapacityRefMap, CapacityRefMap > ResGraph;
91 typedef typename ResGraph::Node ResNode;
92 typedef typename ResGraph::NodeIt ResNodeIt;
93 typedef typename ResGraph::Edge ResEdge;
94 typedef typename ResGraph::EdgeIt ResEdgeIt;
98 /// \brief The type of the flow map.
99 typedef CapacityRefMap FlowMap;
100 /// \brief The type of the potential map.
101 typedef typename Graph::template NodeMap<Cost> PotentialMap;
105 /// \brief Map adaptor class for handling reduced edge costs.
106 class ReducedCostMap : public MapBase<ResEdge, Cost>
111 const CostMap &cost_map;
112 const PotentialMap &pot_map;
116 typedef typename MapBase<ResEdge, Cost>::Value Value;
117 typedef typename MapBase<ResEdge, Cost>::Key Key;
119 ReducedCostMap( const ResGraph &_gr,
120 const CostMap &_cost,
121 const PotentialMap &_pot ) :
122 gr(_gr), cost_map(_cost), pot_map(_pot) {}
124 Value operator[](const Key &e) const {
125 return ResGraph::forward(e) ?
126 cost_map[e] - pot_map[gr.source(e)] + pot_map[gr.target(e)] :
127 -cost_map[e] - pot_map[gr.source(e)] + pot_map[gr.target(e)];
130 }; //class ReducedCostMap
132 /// \brief Map adaptor for \ref lemon::Dijkstra "Dijkstra" class to
133 /// update node potentials.
134 class PotentialUpdateMap : public MapBase<ResNode, Cost>
139 typedef std::pair<ResNode, Cost> Pair;
140 std::vector<Pair> data;
144 typedef typename MapBase<ResNode, Cost>::Value Value;
145 typedef typename MapBase<ResNode, Cost>::Key Key;
147 void potentialMap(PotentialMap &_pot) {
155 void set(const Key &n, const Value &v) {
156 data.push_back(Pair(n, v));
160 Cost val = data[data.size()-1].second;
161 for (int i = 0; i < data.size()-1; ++i)
162 (*pot)[data[i].first] += val - data[i].second;
165 }; //class PotentialUpdateMap
168 /// \brief Map adaptor class for identifing deficit nodes.
169 class DeficitBoolMap : public MapBase<ResNode, bool>
173 const SupplyRefMap &imb;
174 const Capacity δ
178 DeficitBoolMap(const SupplyRefMap &_imb, const Capacity &_delta) :
179 imb(_imb), delta(_delta) {}
181 bool operator[](const ResNode &n) const {
182 return imb[n] <= -delta;
185 }; //class DeficitBoolMap
187 /// \brief Map adaptor class for filtering edges with at least
188 /// \c delta residual capacity
189 class DeltaFilterMap : public MapBase<ResEdge, bool>
194 const Capacity δ
198 typedef typename MapBase<ResEdge, Cost>::Value Value;
199 typedef typename MapBase<ResEdge, Cost>::Key Key;
201 DeltaFilterMap(const ResGraph &_gr, const Capacity &_delta) :
202 gr(_gr), delta(_delta) {}
204 Value operator[](const Key &e) const {
205 return gr.rescap(e) >= delta;
208 }; //class DeltaFilterMap
210 typedef EdgeSubGraphAdaptor<const ResGraph, const DeltaFilterMap>
213 /// \brief Traits class for \ref lemon::Dijkstra "Dijkstra" class.
214 class ResDijkstraTraits :
215 public DijkstraDefaultTraits<DeltaResGraph, ReducedCostMap>
219 typedef PotentialUpdateMap DistMap;
221 static DistMap *createDistMap(const DeltaResGraph&) {
222 return new DistMap();
225 }; //class ResDijkstraTraits
227 #else //WITHOUT_CAPACITY_SCALING
228 /// \brief Map adaptor class for identifing deficit nodes.
229 class DeficitBoolMap : public MapBase<ResNode, bool>
233 const SupplyRefMap &imb;
237 DeficitBoolMap(const SupplyRefMap &_imb) : imb(_imb) {}
239 bool operator[](const ResNode &n) const {
243 }; //class DeficitBoolMap
245 /// \brief Traits class for \ref lemon::Dijkstra "Dijkstra" class.
246 class ResDijkstraTraits :
247 public DijkstraDefaultTraits<ResGraph, ReducedCostMap>
251 typedef PotentialUpdateMap DistMap;
253 static DistMap *createDistMap(const ResGraph&) {
254 return new DistMap();
257 }; //class ResDijkstraTraits
262 /// \brief The directed graph the algorithm runs on.
264 /// \brief The original lower bound map.
265 const LowerMap *lower;
266 /// \brief The modified capacity map.
267 CapacityRefMap capacity;
268 /// \brief The cost map.
270 /// \brief The modified supply map.
272 /// \brief The sum of supply values equals zero.
275 /// \brief The edge map of the current flow.
277 /// \brief The potential node map.
278 PotentialMap potential;
279 /// \brief The residual graph.
281 /// \brief The reduced cost map.
282 ReducedCostMap red_cost;
284 /// \brief The imbalance map.
285 SupplyRefMap imbalance;
286 /// \brief The excess nodes.
287 std::vector<ResNode> excess_nodes;
288 /// \brief The index of the next excess node.
292 typedef Dijkstra<DeltaResGraph, ReducedCostMap, ResDijkstraTraits>
294 /// \brief \ref lemon::Dijkstra "Dijkstra" class for finding
295 /// shortest paths in the residual graph with respect to the
296 /// reduced edge costs.
297 ResDijkstra dijkstra;
299 /// \brief The delta parameter used for capacity scaling.
301 /// \brief Edge filter map.
302 DeltaFilterMap delta_filter;
303 /// \brief The delta residual graph.
304 DeltaResGraph dres_graph;
305 /// \brief Map for identifing deficit nodes.
306 DeficitBoolMap delta_deficit;
308 /// \brief The deficit nodes.
309 std::vector<ResNode> deficit_nodes;
311 #else //WITHOUT_CAPACITY_SCALING
312 typedef Dijkstra<ResGraph, ReducedCostMap, ResDijkstraTraits>
314 /// \brief \ref lemon::Dijkstra "Dijkstra" class for finding
315 /// shortest paths in the residual graph with respect to the
316 /// reduced edge costs.
317 ResDijkstra dijkstra;
318 /// \brief Map for identifing deficit nodes.
319 DeficitBoolMap has_deficit;
322 /// \brief Pred map for the \ref lemon::Dijkstra "Dijkstra" class.
323 typename ResDijkstra::PredMap pred;
324 /// \brief Dist map for the \ref lemon::Dijkstra "Dijkstra" class to
325 /// update node potentials.
326 PotentialUpdateMap updater;
330 /// \brief General constructor of the class (with lower bounds).
332 /// General constructor of the class (with lower bounds).
334 /// \param _graph The directed graph the algorithm runs on.
335 /// \param _lower The lower bounds of the edges.
336 /// \param _capacity The capacities (upper bounds) of the edges.
337 /// \param _cost The cost (length) values of the edges.
338 /// \param _supply The supply values of the nodes (signed).
339 CapacityScaling( const Graph &_graph,
340 const LowerMap &_lower,
341 const CapacityMap &_capacity,
342 const CostMap &_cost,
343 const SupplyMap &_supply ) :
344 graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
345 supply(_graph), flow(_graph, 0), potential(_graph, 0),
346 res_graph(_graph, capacity, flow),
347 red_cost(res_graph, cost, potential), imbalance(_graph),
349 delta(0), delta_filter(res_graph, delta),
350 dres_graph(res_graph, delta_filter),
351 dijkstra(dres_graph, red_cost), pred(dres_graph),
352 delta_deficit(imbalance, delta)
353 #else //WITHOUT_CAPACITY_SCALING
354 dijkstra(res_graph, red_cost), pred(res_graph),
355 has_deficit(imbalance)
358 // Removing nonzero lower bounds
359 capacity = subMap(_capacity, _lower);
361 for (NodeIt n(graph); n != INVALID; ++n) {
362 Supply s = _supply[n];
363 for (InEdgeIt e(graph, n); e != INVALID; ++e)
365 for (OutEdgeIt e(graph, n); e != INVALID; ++e)
367 supply[n] = imbalance[n] = s;
370 valid_supply = sum == 0;
373 /// \brief General constructor of the class (without lower bounds).
375 /// General constructor of the class (without lower bounds).
377 /// \param _graph The directed graph the algorithm runs on.
378 /// \param _capacity The capacities (upper bounds) of the edges.
379 /// \param _cost The cost (length) values of the edges.
380 /// \param _supply The supply values of the nodes (signed).
381 CapacityScaling( const Graph &_graph,
382 const CapacityMap &_capacity,
383 const CostMap &_cost,
384 const SupplyMap &_supply ) :
385 graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
386 supply(_supply), flow(_graph, 0), potential(_graph, 0),
387 res_graph(_graph, capacity, flow),
388 red_cost(res_graph, cost, potential), imbalance(_graph),
390 delta(0), delta_filter(res_graph, delta),
391 dres_graph(res_graph, delta_filter),
392 dijkstra(dres_graph, red_cost), pred(dres_graph),
393 delta_deficit(imbalance, delta)
394 #else //WITHOUT_CAPACITY_SCALING
395 dijkstra(res_graph, red_cost), pred(res_graph),
396 has_deficit(imbalance)
399 // Checking the sum of supply values
401 for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n];
402 valid_supply = sum == 0;
405 /// \brief Simple constructor of the class (with lower bounds).
407 /// Simple constructor of the class (with lower bounds).
409 /// \param _graph The directed graph the algorithm runs on.
410 /// \param _lower The lower bounds of the edges.
411 /// \param _capacity The capacities (upper bounds) of the edges.
412 /// \param _cost The cost (length) values of the edges.
413 /// \param _s The source node.
414 /// \param _t The target node.
415 /// \param _flow_value The required amount of flow from node \c _s
416 /// to node \c _t (i.e. the supply of \c _s and the demand of
418 CapacityScaling( const Graph &_graph,
419 const LowerMap &_lower,
420 const CapacityMap &_capacity,
421 const CostMap &_cost,
423 Supply _flow_value ) :
424 graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
425 supply(_graph), flow(_graph, 0), potential(_graph, 0),
426 res_graph(_graph, capacity, flow),
427 red_cost(res_graph, cost, potential), imbalance(_graph),
429 delta(0), delta_filter(res_graph, delta),
430 dres_graph(res_graph, delta_filter),
431 dijkstra(dres_graph, red_cost), pred(dres_graph),
432 delta_deficit(imbalance, delta)
433 #else //WITHOUT_CAPACITY_SCALING
434 dijkstra(res_graph, red_cost), pred(res_graph),
435 has_deficit(imbalance)
438 // Removing nonzero lower bounds
439 capacity = subMap(_capacity, _lower);
440 for (NodeIt n(graph); n != INVALID; ++n) {
442 if (n == _s) s = _flow_value;
443 if (n == _t) s = -_flow_value;
444 for (InEdgeIt e(graph, n); e != INVALID; ++e)
446 for (OutEdgeIt e(graph, n); e != INVALID; ++e)
448 supply[n] = imbalance[n] = s;
453 /// \brief Simple constructor of the class (without lower bounds).
455 /// Simple constructor of the class (without lower bounds).
457 /// \param _graph The directed graph the algorithm runs on.
458 /// \param _capacity The capacities (upper bounds) of the edges.
459 /// \param _cost The cost (length) values of the edges.
460 /// \param _s The source node.
461 /// \param _t The target node.
462 /// \param _flow_value The required amount of flow from node \c _s
463 /// to node \c _t (i.e. the supply of \c _s and the demand of
465 CapacityScaling( const Graph &_graph,
466 const CapacityMap &_capacity,
467 const CostMap &_cost,
469 Supply _flow_value ) :
470 graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
471 supply(_graph, 0), flow(_graph, 0), potential(_graph, 0),
472 res_graph(_graph, capacity, flow),
473 red_cost(res_graph, cost, potential), imbalance(_graph),
475 delta(0), delta_filter(res_graph, delta),
476 dres_graph(res_graph, delta_filter),
477 dijkstra(dres_graph, red_cost), pred(dres_graph),
478 delta_deficit(imbalance, delta)
479 #else //WITHOUT_CAPACITY_SCALING
480 dijkstra(res_graph, red_cost), pred(res_graph),
481 has_deficit(imbalance)
484 supply[_s] = _flow_value;
485 supply[_t] = -_flow_value;
489 /// \brief Returns a const reference to the flow map.
491 /// Returns a const reference to the flow map.
493 /// \pre \ref run() must be called before using this function.
494 const FlowMap& flowMap() const {
498 /// \brief Returns a const reference to the potential map (the dual
501 /// Returns a const reference to the potential map (the dual
504 /// \pre \ref run() must be called before using this function.
505 const PotentialMap& potentialMap() const {
509 /// \brief Returns the total cost of the found flow.
511 /// Returns the total cost of the found flow. The complexity of the
512 /// function is \f$ O(e) \f$.
514 /// \pre \ref run() must be called before using this function.
515 Cost totalCost() const {
517 for (EdgeIt e(graph); e != INVALID; ++e)
518 c += flow[e] * cost[e];
522 /// \brief Runs the algorithm.
524 /// Runs the algorithm.
526 /// \return \c true if a feasible flow can be found.
528 return init() && start();
533 /// \brief Initializes the algorithm.
535 if (!valid_supply) return false;
537 // Initalizing Dijkstra class
538 updater.potentialMap(potential);
539 dijkstra.distMap(updater).predMap(pred);
542 // Initilaizing delta value
543 Supply max_sup = 0, max_dem = 0;
544 for (NodeIt n(graph); n != INVALID; ++n) {
545 if (supply[n] > max_sup) max_sup = supply[n];
546 if (supply[n] < -max_dem) max_dem = -supply[n];
548 if (max_dem < max_sup) max_sup = max_dem;
549 for ( delta = 1; SCALING_FACTOR * delta < max_sup;
550 delta *= SCALING_FACTOR ) ;
556 /// \brief Executes the capacity scaling version of the successive
557 /// shortest path algorithm.
559 typedef typename DeltaResGraph::EdgeIt DeltaResEdgeIt;
560 typedef typename DeltaResGraph::Edge DeltaResEdge;
565 // Processing capacity scaling phases
567 for ( ; delta >= 1; delta = delta < SCALING_FACTOR && delta > 1 ?
568 1 : delta / SCALING_FACTOR )
570 // Saturating edges not satisfying the optimality condition
572 for (DeltaResEdgeIt e(dres_graph); e != INVALID; ++e) {
573 if (red_cost[e] < 0) {
574 res_graph.augment(e, r = res_graph.rescap(e));
575 imbalance[dres_graph.target(e)] += r;
576 imbalance[dres_graph.source(e)] -= r;
580 // Finding excess nodes
581 excess_nodes.clear();
582 deficit_nodes.clear();
583 for (ResNodeIt n(res_graph); n != INVALID; ++n) {
584 if (imbalance[n] >= delta) excess_nodes.push_back(n);
585 if (imbalance[n] <= -delta) deficit_nodes.push_back(n);
589 // Finding shortest paths
590 while (next_node < excess_nodes.size()) {
591 // Checking deficit nodes
593 bool delta_def = false;
594 for (int i = 0; i < deficit_nodes.size(); ++i) {
595 if (imbalance[deficit_nodes[i]] <= -delta) {
600 if (!delta_def) break;
604 s = excess_nodes[next_node];
607 dijkstra.addSource(s);
611 if ((t = dijkstra.start(delta_deficit)) == INVALID) {
619 // Updating node potentials
622 // Augment along a shortest path from s to t
623 Capacity d = imbalance[s] < -imbalance[t] ?
624 imbalance[s] : -imbalance[t];
628 while ((e = pred[u]) != INVALID) {
629 if (res_graph.rescap(e) < d) d = res_graph.rescap(e);
630 u = dres_graph.source(e);
634 while ((e = pred[u]) != INVALID) {
635 res_graph.augment(e, d);
636 u = dres_graph.source(e);
640 if (imbalance[s] < delta) ++next_node;
644 std::cout << "Cost Scaling algorithm finished with running Dijkstra algorithm "
645 << dijk_num << " times." << std::endl;
648 // Handling nonzero lower bounds
650 for (EdgeIt e(graph); e != INVALID; ++e)
651 flow[e] += (*lower)[e];
656 #else //WITHOUT_CAPACITY_SCALING
657 /// \brief Executes the successive shortest path algorithm without
658 /// capacity scaling.
660 // Finding excess nodes
661 for (ResNodeIt n(res_graph); n != INVALID; ++n) {
662 if (imbalance[n] > 0) excess_nodes.push_back(n);
664 if (excess_nodes.size() == 0) return true;
667 // Finding shortest paths
669 while ( imbalance[excess_nodes[next_node]] > 0 ||
670 ++next_node < excess_nodes.size() )
673 s = excess_nodes[next_node];
676 dijkstra.addSource(s);
677 if ((t = dijkstra.start(has_deficit)) == INVALID)
680 // Updating node potentials
683 // Augmenting along a shortest path from s to t
684 Capacity delta = imbalance[s] < -imbalance[t] ?
685 imbalance[s] : -imbalance[t];
688 while ((e = pred[u]) != INVALID) {
689 if (res_graph.rescap(e) < delta) delta = res_graph.rescap(e);
690 u = res_graph.source(e);
693 while ((e = pred[u]) != INVALID) {
694 res_graph.augment(e, delta);
695 u = res_graph.source(e);
697 imbalance[s] -= delta;
698 imbalance[t] += delta;
701 // Handling nonzero lower bounds
703 for (EdgeIt e(graph); e != INVALID; ++e)
704 flow[e] += (*lower)[e];
710 }; //class CapacityScaling
716 #endif //LEMON_CAPACITY_SCALING_H