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>
36 /// \addtogroup min_cost_flow
39 /// \brief Implementation of the capacity scaling version of the
40 /// succesive shortest path algorithm for finding a minimum cost flow.
42 /// \ref lemon::CapacityScaling "CapacityScaling" implements a
43 /// capacity scaling algorithm for finding a minimum cost flow.
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 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;
83 typedef ResGraphAdaptor< const Graph, Capacity,
84 CapacityRefMap, CapacityRefMap > 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 /// \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 Map adaptor class for handling reduced edge costs.
100 class ReducedCostMap : public MapBase<ResEdge, Cost>
105 const CostMap &cost_map;
106 const PotentialMap &pot_map;
110 typedef typename MapBase<ResEdge, Cost>::Value Value;
111 typedef typename MapBase<ResEdge, Cost>::Key Key;
113 ReducedCostMap( const ResGraph &_gr,
114 const CostMap &_cost,
115 const PotentialMap &_pot ) :
116 gr(_gr), cost_map(_cost), pot_map(_pot) {}
118 Value operator[](const Key &e) const {
119 return ResGraph::forward(e) ?
120 cost_map[e] - pot_map[gr.source(e)] + pot_map[gr.target(e)] :
121 -cost_map[e] - pot_map[gr.source(e)] + pot_map[gr.target(e)];
124 }; //class ReducedCostMap
126 /// \brief Map adaptor for \ref lemon::Dijkstra "Dijkstra" class to
127 /// update node potentials.
128 class PotentialUpdateMap : public MapBase<ResNode, Cost>
133 typedef std::pair<ResNode, Cost> Pair;
134 std::vector<Pair> data;
138 typedef typename MapBase<ResNode, Cost>::Value Value;
139 typedef typename MapBase<ResNode, Cost>::Key Key;
141 void potentialMap(PotentialMap &_pot) {
149 void set(const Key &n, const Value &v) {
150 data.push_back(Pair(n, v));
154 Cost val = data[data.size()-1].second;
155 for (int i = 0; i < data.size()-1; ++i)
156 (*pot)[data[i].first] += val - data[i].second;
159 }; //class PotentialUpdateMap
162 /// \brief Map adaptor class for identifing deficit nodes.
163 class DeficitBoolMap : public MapBase<ResNode, bool>
167 const SupplyRefMap &imb;
168 const Capacity δ
172 DeficitBoolMap(const SupplyRefMap &_imb, const Capacity &_delta) :
173 imb(_imb), delta(_delta) {}
175 bool operator[](const ResNode &n) const {
176 return imb[n] <= -delta;
179 }; //class DeficitBoolMap
181 /// \brief Map adaptor class for filtering edges with at least
182 /// \c delta residual capacity
183 class DeltaFilterMap : public MapBase<ResEdge, bool>
188 const Capacity δ
192 typedef typename MapBase<ResEdge, Cost>::Value Value;
193 typedef typename MapBase<ResEdge, Cost>::Key Key;
195 DeltaFilterMap(const ResGraph &_gr, const Capacity &_delta) :
196 gr(_gr), delta(_delta) {}
198 Value operator[](const Key &e) const {
199 return gr.rescap(e) >= delta;
202 }; //class DeltaFilterMap
204 typedef EdgeSubGraphAdaptor<const ResGraph, const DeltaFilterMap>
207 /// \brief Traits class for \ref lemon::Dijkstra "Dijkstra" class.
208 class ResDijkstraTraits :
209 public DijkstraDefaultTraits<DeltaResGraph, ReducedCostMap>
213 typedef PotentialUpdateMap DistMap;
215 static DistMap *createDistMap(const DeltaResGraph&) {
216 return new DistMap();
219 }; //class ResDijkstraTraits
221 #else //WITHOUT_CAPACITY_SCALING
222 /// \brief Map adaptor class for identifing deficit nodes.
223 class DeficitBoolMap : public MapBase<ResNode, bool>
227 const SupplyRefMap &imb;
231 DeficitBoolMap(const SupplyRefMap &_imb) : imb(_imb) {}
233 bool operator[](const ResNode &n) const {
237 }; //class DeficitBoolMap
239 /// \brief Traits class for \ref lemon::Dijkstra "Dijkstra" class.
240 class ResDijkstraTraits :
241 public DijkstraDefaultTraits<ResGraph, ReducedCostMap>
245 typedef PotentialUpdateMap DistMap;
247 static DistMap *createDistMap(const ResGraph&) {
248 return new DistMap();
251 }; //class ResDijkstraTraits
256 /// \brief The directed graph the algorithm runs on.
258 /// \brief The original lower bound map.
259 const LowerMap *lower;
260 /// \brief The modified capacity map.
261 CapacityRefMap capacity;
262 /// \brief The cost map.
264 /// \brief The modified supply map.
266 /// \brief The sum of supply values equals zero.
269 /// \brief The edge map of the current flow.
271 /// \brief The potential node map.
272 PotentialMap potential;
273 /// \brief The residual graph.
275 /// \brief The reduced cost map.
276 ReducedCostMap red_cost;
278 /// \brief The imbalance map.
279 SupplyRefMap imbalance;
280 /// \brief The excess nodes.
281 std::vector<ResNode> excess_nodes;
282 /// \brief The index of the next excess node.
286 typedef Dijkstra<DeltaResGraph, ReducedCostMap, ResDijkstraTraits>
288 /// \brief \ref lemon::Dijkstra "Dijkstra" class for finding
289 /// shortest paths in the residual graph with respect to the
290 /// reduced edge costs.
291 ResDijkstra dijkstra;
293 /// \brief The delta parameter used for capacity scaling.
295 /// \brief Edge filter map.
296 DeltaFilterMap delta_filter;
297 /// \brief The delta residual graph.
298 DeltaResGraph dres_graph;
299 /// \brief Map for identifing deficit nodes.
300 DeficitBoolMap delta_deficit;
302 #else //WITHOUT_CAPACITY_SCALING
303 typedef Dijkstra<ResGraph, ReducedCostMap, ResDijkstraTraits>
305 /// \brief \ref lemon::Dijkstra "Dijkstra" class for finding
306 /// shortest paths in the residual graph with respect to the
307 /// reduced edge costs.
308 ResDijkstra dijkstra;
309 /// \brief Map for identifing deficit nodes.
310 DeficitBoolMap has_deficit;
313 /// \brief Pred map for the \ref lemon::Dijkstra "Dijkstra" class.
314 typename ResDijkstra::PredMap pred;
315 /// \brief Dist map for the \ref lemon::Dijkstra "Dijkstra" class to
316 /// update node potentials.
317 PotentialUpdateMap updater;
321 /// \brief General constructor of the class (with lower bounds).
323 /// General constructor of the class (with lower bounds).
325 /// \param _graph The directed graph the algorithm runs on.
326 /// \param _lower The lower bounds of the edges.
327 /// \param _capacity The capacities (upper bounds) of the edges.
328 /// \param _cost The cost (length) values of the edges.
329 /// \param _supply The supply values of the nodes (signed).
330 CapacityScaling( const Graph &_graph,
331 const LowerMap &_lower,
332 const CapacityMap &_capacity,
333 const CostMap &_cost,
334 const SupplyMap &_supply ) :
335 graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
336 supply(_graph), flow(_graph, 0), potential(_graph, 0),
337 res_graph(_graph, capacity, flow),
338 red_cost(res_graph, cost, potential), imbalance(_graph),
340 delta(0), delta_filter(res_graph, delta),
341 dres_graph(res_graph, delta_filter),
342 dijkstra(dres_graph, red_cost), pred(dres_graph),
343 delta_deficit(imbalance, delta)
344 #else //WITHOUT_CAPACITY_SCALING
345 dijkstra(res_graph, red_cost), pred(res_graph),
346 has_deficit(imbalance)
349 // Removing nonzero lower bounds
350 capacity = subMap(_capacity, _lower);
352 for (NodeIt n(graph); n != INVALID; ++n) {
353 Supply s = _supply[n];
354 for (InEdgeIt e(graph, n); e != INVALID; ++e)
356 for (OutEdgeIt e(graph, n); e != INVALID; ++e)
358 supply[n] = imbalance[n] = s;
361 valid_supply = sum == 0;
364 /// \brief General constructor of the class (without lower bounds).
366 /// General constructor of the class (without lower bounds).
368 /// \param _graph The directed graph the algorithm runs on.
369 /// \param _capacity The capacities (upper bounds) of the edges.
370 /// \param _cost The cost (length) values of the edges.
371 /// \param _supply The supply values of the nodes (signed).
372 CapacityScaling( const Graph &_graph,
373 const CapacityMap &_capacity,
374 const CostMap &_cost,
375 const SupplyMap &_supply ) :
376 graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
377 supply(_supply), flow(_graph, 0), potential(_graph, 0),
378 res_graph(_graph, capacity, flow),
379 red_cost(res_graph, cost, potential), imbalance(_graph),
381 delta(0), delta_filter(res_graph, delta),
382 dres_graph(res_graph, delta_filter),
383 dijkstra(dres_graph, red_cost), pred(dres_graph),
384 delta_deficit(imbalance, delta)
385 #else //WITHOUT_CAPACITY_SCALING
386 dijkstra(res_graph, red_cost), pred(res_graph),
387 has_deficit(imbalance)
390 // Checking the sum of supply values
392 for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n];
393 valid_supply = sum == 0;
396 /// \brief Simple constructor of the class (with lower bounds).
398 /// Simple constructor of the class (with lower bounds).
400 /// \param _graph The directed graph the algorithm runs on.
401 /// \param _lower The lower bounds of the edges.
402 /// \param _capacity The capacities (upper bounds) of the edges.
403 /// \param _cost The cost (length) values of the edges.
404 /// \param _s The source node.
405 /// \param _t The target node.
406 /// \param _flow_value The required amount of flow from node \c _s
407 /// to node \c _t (i.e. the supply of \c _s and the demand of
409 CapacityScaling( const Graph &_graph,
410 const LowerMap &_lower,
411 const CapacityMap &_capacity,
412 const CostMap &_cost,
414 Supply _flow_value ) :
415 graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
416 supply(_graph), flow(_graph, 0), potential(_graph, 0),
417 res_graph(_graph, capacity, flow),
418 red_cost(res_graph, cost, potential), imbalance(_graph),
420 delta(0), delta_filter(res_graph, delta),
421 dres_graph(res_graph, delta_filter),
422 dijkstra(dres_graph, red_cost), pred(dres_graph),
423 delta_deficit(imbalance, delta)
424 #else //WITHOUT_CAPACITY_SCALING
425 dijkstra(res_graph, red_cost), pred(res_graph),
426 has_deficit(imbalance)
429 // Removing nonzero lower bounds
430 capacity = subMap(_capacity, _lower);
431 for (NodeIt n(graph); n != INVALID; ++n) {
433 if (n == _s) s = _flow_value;
434 if (n == _t) s = -_flow_value;
435 for (InEdgeIt e(graph, n); e != INVALID; ++e)
437 for (OutEdgeIt e(graph, n); e != INVALID; ++e)
439 supply[n] = imbalance[n] = s;
444 /// \brief Simple constructor of the class (without lower bounds).
446 /// Simple constructor of the class (without lower bounds).
448 /// \param _graph The directed graph the algorithm runs on.
449 /// \param _capacity The capacities (upper bounds) of the edges.
450 /// \param _cost The cost (length) values of the edges.
451 /// \param _s The source node.
452 /// \param _t The target node.
453 /// \param _flow_value The required amount of flow from node \c _s
454 /// to node \c _t (i.e. the supply of \c _s and the demand of
456 CapacityScaling( const Graph &_graph,
457 const CapacityMap &_capacity,
458 const CostMap &_cost,
460 Supply _flow_value ) :
461 graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
462 supply(_graph, 0), flow(_graph, 0), potential(_graph, 0),
463 res_graph(_graph, capacity, flow),
464 red_cost(res_graph, cost, potential), imbalance(_graph),
466 delta(0), delta_filter(res_graph, delta),
467 dres_graph(res_graph, delta_filter),
468 dijkstra(dres_graph, red_cost), pred(dres_graph),
469 delta_deficit(imbalance, delta)
470 #else //WITHOUT_CAPACITY_SCALING
471 dijkstra(res_graph, red_cost), pred(res_graph),
472 has_deficit(imbalance)
475 supply[_s] = _flow_value;
476 supply[_t] = -_flow_value;
480 /// \brief Returns a const reference to the flow map.
482 /// Returns a const reference to the flow map.
484 /// \pre \ref run() must be called before using this function.
485 const FlowMap& flowMap() const {
489 /// \brief Returns a const reference to the potential map (the dual
492 /// Returns a const reference to the potential map (the dual
495 /// \pre \ref run() must be called before using this function.
496 const PotentialMap& potentialMap() const {
500 /// \brief Returns the total cost of the found flow.
502 /// Returns the total cost of the found flow. The complexity of the
503 /// function is \f$ O(e) \f$.
505 /// \pre \ref run() must be called before using this function.
506 Cost totalCost() const {
508 for (EdgeIt e(graph); e != INVALID; ++e)
509 c += flow[e] * cost[e];
513 /// \brief Runs the successive shortest path algorithm.
515 /// Runs the successive shortest path algorithm.
517 /// \return \c true if a feasible flow can be found.
519 return init() && start();
524 /// \brief Initializes the algorithm.
526 if (!valid_supply) return false;
528 // Initalizing Dijkstra class
529 updater.potentialMap(potential);
530 dijkstra.distMap(updater).predMap(pred);
533 // Initilaizing delta value
534 Capacity max_cap = 0;
535 for (EdgeIt e(graph); e != INVALID; ++e) {
536 if (capacity[e] > max_cap) max_cap = capacity[e];
538 for (delta = 1; 2 * delta < max_cap; delta *= 2) ;
544 /// \brief Executes the capacity scaling version of the successive
545 /// shortest path algorithm.
547 typedef typename DeltaResGraph::EdgeIt DeltaResEdgeIt;
548 typedef typename DeltaResGraph::Edge DeltaResEdge;
550 // Processing capacity scaling phases
552 for ( ; delta >= 1; delta = delta < 4 && delta > 1 ?
555 // Saturating edges not satisfying the optimality condition
557 for (DeltaResEdgeIt e(dres_graph); e != INVALID; ++e) {
558 if (red_cost[e] < 0) {
559 res_graph.augment(e, r = res_graph.rescap(e));
560 imbalance[dres_graph.target(e)] += r;
561 imbalance[dres_graph.source(e)] -= r;
565 // Finding excess nodes
566 excess_nodes.clear();
567 for (ResNodeIt n(res_graph); n != INVALID; ++n) {
568 if (imbalance[n] >= delta) excess_nodes.push_back(n);
572 // Finding successive shortest paths
573 while (next_node < excess_nodes.size()) {
575 s = excess_nodes[next_node];
578 dijkstra.addSource(s);
579 if ((t = dijkstra.start(delta_deficit)) == INVALID) {
587 // Updating node potentials
590 // Augment along a shortest path from s to t
591 Capacity d = imbalance[s] < -imbalance[t] ?
592 imbalance[s] : -imbalance[t];
596 while ((e = pred[u]) != INVALID) {
597 if (res_graph.rescap(e) < d) d = res_graph.rescap(e);
598 u = dres_graph.source(e);
602 while ((e = pred[u]) != INVALID) {
603 res_graph.augment(e, d);
604 u = dres_graph.source(e);
608 if (imbalance[s] < delta) ++next_node;
612 // Handling nonzero lower bounds
614 for (EdgeIt e(graph); e != INVALID; ++e)
615 flow[e] += (*lower)[e];
620 #else //WITHOUT_CAPACITY_SCALING
621 /// \brief Executes the successive shortest path algorithm without
622 /// capacity scaling.
624 // Finding excess nodes
625 for (ResNodeIt n(res_graph); n != INVALID; ++n) {
626 if (imbalance[n] > 0) excess_nodes.push_back(n);
628 if (excess_nodes.size() == 0) return true;
631 // Finding successive shortest paths
633 while ( imbalance[excess_nodes[next_node]] > 0 ||
634 ++next_node < excess_nodes.size() )
637 s = excess_nodes[next_node];
640 dijkstra.addSource(s);
641 if ((t = dijkstra.start(has_deficit)) == INVALID)
644 // Updating node potentials
647 // Augmenting along a shortest path from s to t
648 Capacity delta = imbalance[s] < -imbalance[t] ?
649 imbalance[s] : -imbalance[t];
652 while ((e = pred[u]) != INVALID) {
653 if (res_graph.rescap(e) < delta) delta = res_graph.rescap(e);
654 u = res_graph.source(e);
657 while ((e = pred[u]) != INVALID) {
658 res_graph.augment(e, delta);
659 u = res_graph.source(e);
661 imbalance[s] -= delta;
662 imbalance[t] += delta;
665 // Handling nonzero lower bounds
667 for (EdgeIt e(graph); e != INVALID; ++e)
668 flow[e] += (*lower)[e];
674 }; //class CapacityScaling
680 #endif //LEMON_CAPACITY_SCALING_H