Major improvements in NetworkSimplex.
Main changes:
- Use -potenital[] instead of potential[] to conform to the usual
terminology.
- Use function parameter instead of #define commands to select pivot rule.
- Use much faster implementation for the candidate list pivot rule.
It is about 5-20 times faster now.
- Add a new pivot rule called "Limited Search" that is a modified
version of "Block Search". It is about 25 percent faster on rather
sparse graphs.
- By default "Limited Search" is used for sparse graphs and
"Block Search" is used otherwise. This combined method is the most
efficient on every input class.
- 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.
- Many 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 Capacity scaling algorithm for finding a minimum cost flow.
29 #include <lemon/graph_adaptor.h>
30 #include <lemon/bin_heap.h>
34 /// \addtogroup min_cost_flow
37 /// \brief Implementation of the capacity scaling algorithm for
38 /// finding a minimum cost flow.
40 /// \ref CapacityScaling implements the capacity scaling version
41 /// of the successive shortest path algorithm for finding a minimum
44 /// \tparam Graph The directed graph type the algorithm runs on.
45 /// \tparam LowerMap The type of the lower bound map.
46 /// \tparam CapacityMap The type of the capacity (upper bound) map.
47 /// \tparam CostMap The type of the cost (length) map.
48 /// \tparam SupplyMap The type of the supply map.
51 /// - Edge capacities and costs should be \e non-negative \e integers.
52 /// - Supply values should be \e signed \e integers.
53 /// - \c LowerMap::Value must be convertible to \c CapacityMap::Value.
54 /// - \c CapacityMap::Value and \c SupplyMap::Value must be
55 /// convertible to each other.
56 /// - All value types must be convertible to \c CostMap::Value, which
57 /// must be signed type.
59 /// \author Peter Kovacs
61 template < typename Graph,
62 typename LowerMap = typename Graph::template EdgeMap<int>,
63 typename CapacityMap = typename Graph::template EdgeMap<int>,
64 typename CostMap = typename Graph::template EdgeMap<int>,
65 typename SupplyMap = typename Graph::template NodeMap<int> >
68 GRAPH_TYPEDEFS(typename Graph);
70 typedef typename CapacityMap::Value Capacity;
71 typedef typename CostMap::Value Cost;
72 typedef typename SupplyMap::Value Supply;
73 typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap;
74 typedef typename Graph::template NodeMap<Supply> SupplyNodeMap;
75 typedef typename Graph::template NodeMap<Edge> PredMap;
79 /// The type of the flow map.
80 typedef typename Graph::template EdgeMap<Capacity> FlowMap;
81 /// The type of the potential map.
82 typedef typename Graph::template NodeMap<Cost> PotentialMap;
86 /// \brief Special implementation of the \ref Dijkstra algorithm
87 /// for finding shortest paths in the residual network.
89 /// \ref ResidualDijkstra is a special implementation of the
90 /// \ref Dijkstra algorithm for finding shortest paths in the
91 /// residual network of the graph with respect to the reduced edge
92 /// costs and modifying the node potentials according to the
93 /// distance of the nodes.
94 class ResidualDijkstra
96 typedef typename Graph::template NodeMap<Cost> CostNodeMap;
97 typedef typename Graph::template NodeMap<Edge> PredMap;
99 typedef typename Graph::template NodeMap<int> HeapCrossRef;
100 typedef BinHeap<Cost, HeapCrossRef> Heap;
104 // The directed graph the algorithm runs on
108 const FlowMap &_flow;
109 const CapacityEdgeMap &_res_cap;
110 const CostMap &_cost;
111 const SupplyNodeMap &_excess;
112 PotentialMap &_potential;
118 // The processed (i.e. permanently labeled) nodes
119 std::vector<Node> _proc_nodes;
123 /// The constructor of the class.
124 ResidualDijkstra( const Graph &graph,
126 const CapacityEdgeMap &res_cap,
128 const SupplyMap &excess,
129 PotentialMap &potential,
131 _graph(graph), _flow(flow), _res_cap(res_cap), _cost(cost),
132 _excess(excess), _potential(potential), _dist(graph),
136 /// Runs the algorithm from the given source node.
137 Node run(Node s, Capacity delta) {
138 HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
139 Heap heap(heap_cross_ref);
145 while (!heap.empty() && _excess[heap.top()] > -delta) {
146 Node u = heap.top(), v;
147 Cost d = heap.prio() + _potential[u], nd;
148 _dist[u] = heap.prio();
150 _proc_nodes.push_back(u);
152 // Traversing outgoing edges
153 for (OutEdgeIt e(_graph, u); e != INVALID; ++e) {
154 if (_res_cap[e] >= delta) {
155 v = _graph.target(e);
156 switch(heap.state(v)) {
158 heap.push(v, d + _cost[e] - _potential[v]);
162 nd = d + _cost[e] - _potential[v];
164 heap.decrease(v, nd);
168 case Heap::POST_HEAP:
174 // Traversing incoming edges
175 for (InEdgeIt e(_graph, u); e != INVALID; ++e) {
176 if (_flow[e] >= delta) {
177 v = _graph.source(e);
178 switch(heap.state(v)) {
180 heap.push(v, d - _cost[e] - _potential[v]);
184 nd = d - _cost[e] - _potential[v];
186 heap.decrease(v, nd);
190 case Heap::POST_HEAP:
196 if (heap.empty()) return INVALID;
198 // Updating potentials of processed nodes
200 Cost t_dist = heap.prio();
201 for (int i = 0; i < int(_proc_nodes.size()); ++i)
202 _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
207 }; //class ResidualDijkstra
211 // The directed graph the algorithm runs on
213 // The original lower bound map
214 const LowerMap *_lower;
215 // The modified capacity map
216 CapacityEdgeMap _capacity;
217 // The original cost map
218 const CostMap &_cost;
219 // The modified supply map
220 SupplyNodeMap _supply;
223 // Edge map of the current flow
225 // Node map of the current potentials
226 PotentialMap _potential;
228 // The residual capacity map
229 CapacityEdgeMap _res_cap;
231 SupplyNodeMap _excess;
232 // The excess nodes (i.e. nodes with positive excess)
233 std::vector<Node> _excess_nodes;
234 // The deficit nodes (i.e. nodes with negative excess)
235 std::vector<Node> _deficit_nodes;
237 // The delta parameter used for capacity scaling
239 // The maximum number of phases
244 // Implementation of the Dijkstra algorithm for finding augmenting
245 // shortest paths in the residual network
246 ResidualDijkstra _dijkstra;
250 /// \brief General constructor of the class (with lower bounds).
252 /// General constructor of the class (with lower bounds).
254 /// \param graph The directed graph the algorithm runs on.
255 /// \param lower The lower bounds of the edges.
256 /// \param capacity The capacities (upper bounds) of the edges.
257 /// \param cost The cost (length) values of the edges.
258 /// \param supply The supply values of the nodes (signed).
259 CapacityScaling( const Graph &graph,
260 const LowerMap &lower,
261 const CapacityMap &capacity,
263 const SupplyMap &supply ) :
264 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
265 _supply(graph), _flow(graph, 0), _potential(graph, 0),
266 _res_cap(graph), _excess(graph), _pred(graph),
267 _dijkstra(_graph, _flow, _res_cap, _cost, _excess, _potential, _pred)
269 // Removing non-zero lower bounds
270 _capacity = subMap(capacity, lower);
271 _res_cap = _capacity;
273 for (NodeIt n(_graph); n != INVALID; ++n) {
274 Supply s = supply[n];
275 for (InEdgeIt e(_graph, n); e != INVALID; ++e)
277 for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
282 _valid_supply = sum == 0;
285 /// \brief General constructor of the class (without lower bounds).
287 /// General constructor of the class (without lower bounds).
289 /// \param graph The directed graph the algorithm runs on.
290 /// \param capacity The capacities (upper bounds) of the edges.
291 /// \param cost The cost (length) values of the edges.
292 /// \param supply The supply values of the nodes (signed).
293 CapacityScaling( const Graph &graph,
294 const CapacityMap &capacity,
296 const SupplyMap &supply ) :
297 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
298 _supply(supply), _flow(graph, 0), _potential(graph, 0),
299 _res_cap(capacity), _excess(graph), _pred(graph),
300 _dijkstra(_graph, _flow, _res_cap, _cost, _excess, _potential, _pred)
302 // Checking the sum of supply values
304 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n];
305 _valid_supply = sum == 0;
308 /// \brief Simple constructor of the class (with lower bounds).
310 /// Simple constructor of the class (with lower bounds).
312 /// \param graph The directed graph the algorithm runs on.
313 /// \param lower The lower bounds of the edges.
314 /// \param capacity The capacities (upper bounds) of the edges.
315 /// \param cost The cost (length) values of the edges.
316 /// \param s The source node.
317 /// \param t The target node.
318 /// \param flow_value The required amount of flow from node \c s
319 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
320 CapacityScaling( const Graph &graph,
321 const LowerMap &lower,
322 const CapacityMap &capacity,
325 Supply flow_value ) :
326 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost),
327 _supply(graph), _flow(graph, 0), _potential(graph, 0),
328 _res_cap(graph), _excess(graph), _pred(graph),
329 _dijkstra(_graph, _flow, _res_cap, _cost, _excess, _potential, _pred)
331 // Removing non-zero lower bounds
332 _capacity = subMap(capacity, lower);
333 _res_cap = _capacity;
334 for (NodeIt n(_graph); n != INVALID; ++n) {
336 if (n == s) sum = flow_value;
337 if (n == t) sum = -flow_value;
338 for (InEdgeIt e(_graph, n); e != INVALID; ++e)
340 for (OutEdgeIt e(_graph, n); e != INVALID; ++e)
344 _valid_supply = true;
347 /// \brief Simple constructor of the class (without lower bounds).
349 /// Simple constructor of the class (without lower bounds).
351 /// \param graph The directed graph the algorithm runs on.
352 /// \param capacity The capacities (upper bounds) of the edges.
353 /// \param cost The cost (length) values of the edges.
354 /// \param s The source node.
355 /// \param t The target node.
356 /// \param flow_value The required amount of flow from node \c s
357 /// to node \c t (i.e. the supply of \c s and the demand of \c t).
358 CapacityScaling( const Graph &graph,
359 const CapacityMap &capacity,
362 Supply flow_value ) :
363 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost),
364 _supply(graph, 0), _flow(graph, 0), _potential(graph, 0),
365 _res_cap(capacity), _excess(graph), _pred(graph),
366 _dijkstra(_graph, _flow, _res_cap, _cost, _excess, _potential, _pred)
368 _supply[s] = flow_value;
369 _supply[t] = -flow_value;
370 _valid_supply = true;
373 /// \brief Runs the algorithm.
375 /// Runs the algorithm.
377 /// \param scaling Enable or disable capacity scaling.
378 /// If the maximum edge capacity and/or the amount of total supply
379 /// is rather small, the algorithm could be slightly faster without
382 /// \return \c true if a feasible flow can be found.
383 bool run(bool scaling = true) {
384 return init(scaling) && start();
387 /// \brief Returns a const reference to the edge map storing the
390 /// Returns a const reference to the edge map storing the found flow.
392 /// \pre \ref run() must be called before using this function.
393 const FlowMap& flowMap() const {
397 /// \brief Returns a const reference to the node map storing the
398 /// found potentials (the dual solution).
400 /// Returns a const reference to the node map storing the found
401 /// potentials (the dual solution).
403 /// \pre \ref run() must be called before using this function.
404 const PotentialMap& potentialMap() const {
408 /// \brief Returns the total cost of the found flow.
410 /// Returns the total cost of the found flow. The complexity of the
411 /// function is \f$ O(e) \f$.
413 /// \pre \ref run() must be called before using this function.
414 Cost totalCost() const {
416 for (EdgeIt e(_graph); e != INVALID; ++e)
417 c += _flow[e] * _cost[e];
423 /// Initializes the algorithm.
424 bool init(bool scaling) {
425 if (!_valid_supply) return false;
428 // Initilaizing delta value
431 Supply max_sup = 0, max_dem = 0;
432 for (NodeIt n(_graph); n != INVALID; ++n) {
433 if ( _supply[n] > max_sup) max_sup = _supply[n];
434 if (-_supply[n] > max_dem) max_dem = -_supply[n];
436 if (max_dem < max_sup) max_sup = max_dem;
438 for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2)
449 return startWithScaling();
451 return startWithoutScaling();
454 /// Executes the capacity scaling algorithm.
455 bool startWithScaling() {
456 // Processing capacity scaling phases
461 // Saturating all edges not satisfying the optimality condition
462 for (EdgeIt e(_graph); e != INVALID; ++e) {
463 Node u = _graph.source(e), v = _graph.target(e);
464 Cost c = _cost[e] + _potential[u] - _potential[v];
465 if (c < 0 && _res_cap[e] >= _delta) {
466 _excess[u] -= _res_cap[e];
467 _excess[v] += _res_cap[e];
468 _flow[e] = _capacity[e];
471 else if (c > 0 && _flow[e] >= _delta) {
472 _excess[u] += _flow[e];
473 _excess[v] -= _flow[e];
475 _res_cap[e] = _capacity[e];
479 // Finding excess nodes and deficit nodes
480 _excess_nodes.clear();
481 _deficit_nodes.clear();
482 for (NodeIt n(_graph); n != INVALID; ++n) {
483 if (_excess[n] >= _delta) _excess_nodes.push_back(n);
484 if (_excess[n] <= -_delta) _deficit_nodes.push_back(n);
488 // Finding augmenting shortest paths
489 while (next_node < int(_excess_nodes.size())) {
490 // Checking deficit nodes
492 bool delta_deficit = false;
493 for (int i = 0; i < int(_deficit_nodes.size()); ++i) {
494 if (_excess[_deficit_nodes[i]] <= -_delta) {
495 delta_deficit = true;
499 if (!delta_deficit) break;
503 s = _excess_nodes[next_node];
504 if ((t = _dijkstra.run(s, _delta)) == INVALID) {
512 // Augmenting along a shortest path from s to t.
513 Capacity d = _excess[s] < -_excess[t] ? _excess[s] : -_excess[t];
517 while ((e = _pred[u]) != INVALID) {
519 if (u == _graph.target(e)) {
521 u = _graph.source(e);
524 u = _graph.target(e);
530 while ((e = _pred[u]) != INVALID) {
531 if (u == _graph.target(e)) {
534 u = _graph.source(e);
538 u = _graph.target(e);
544 if (_excess[s] < _delta) ++next_node;
547 if (_delta == 1) break;
548 if (++phase_cnt > _phase_num / 4) factor = 2;
549 _delta = _delta <= factor ? 1 : _delta / factor;
552 // Handling non-zero lower bounds
554 for (EdgeIt e(_graph); e != INVALID; ++e)
555 _flow[e] += (*_lower)[e];
560 /// Executes the successive shortest path algorithm.
561 bool startWithoutScaling() {
562 // Finding excess nodes
563 for (NodeIt n(_graph); n != INVALID; ++n)
564 if (_excess[n] > 0) _excess_nodes.push_back(n);
565 if (_excess_nodes.size() == 0) return true;
568 // Finding shortest paths
570 while ( _excess[_excess_nodes[next_node]] > 0 ||
571 ++next_node < int(_excess_nodes.size()) )
574 s = _excess_nodes[next_node];
575 if ((t = _dijkstra.run(s, 1)) == INVALID)
578 // Augmenting along a shortest path from s to t
579 Capacity d = _excess[s] < -_excess[t] ? _excess[s] : -_excess[t];
582 while ((e = _pred[u]) != INVALID) {
584 if (u == _graph.target(e)) {
586 u = _graph.source(e);
589 u = _graph.target(e);
594 while ((e = _pred[u]) != INVALID) {
595 if (u == _graph.target(e)) {
598 u = _graph.source(e);
602 u = _graph.target(e);
609 // Handling non-zero lower bounds
611 for (EdgeIt e(_graph); e != INVALID; ++e)
612 _flow[e] += (*_lower)[e];
617 }; //class CapacityScaling
623 #endif //LEMON_CAPACITY_SCALING_H