kpeter@805: /* -*- C++ -*- kpeter@805: * kpeter@805: * This file is a part of LEMON, a generic C++ optimization library kpeter@805: * kpeter@805: * Copyright (C) 2003-2008 kpeter@805: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport kpeter@805: * (Egervary Research Group on Combinatorial Optimization, EGRES). kpeter@805: * kpeter@805: * Permission to use, modify and distribute this software is granted kpeter@805: * provided that this copyright notice appears in all copies. For kpeter@805: * precise terms see the accompanying LICENSE file. kpeter@805: * kpeter@805: * This software is provided "AS IS" with no warranty of any kind, kpeter@805: * express or implied, and with no claim as to its suitability for any kpeter@805: * purpose. kpeter@805: * kpeter@805: */ kpeter@805: kpeter@805: #ifndef LEMON_CAPACITY_SCALING_H kpeter@805: #define LEMON_CAPACITY_SCALING_H kpeter@805: kpeter@805: /// \ingroup min_cost_flow kpeter@805: /// kpeter@805: /// \file kpeter@805: /// \brief Capacity scaling algorithm for finding a minimum cost flow. kpeter@805: kpeter@805: #include kpeter@805: #include kpeter@805: kpeter@805: namespace lemon { kpeter@805: kpeter@805: /// \addtogroup min_cost_flow kpeter@805: /// @{ kpeter@805: kpeter@805: /// \brief Implementation of the capacity scaling algorithm for kpeter@805: /// finding a minimum cost flow. kpeter@805: /// kpeter@805: /// \ref CapacityScaling implements the capacity scaling version kpeter@805: /// of the successive shortest path algorithm for finding a minimum kpeter@805: /// cost flow. kpeter@805: /// kpeter@805: /// \tparam Digraph The digraph type the algorithm runs on. kpeter@805: /// \tparam LowerMap The type of the lower bound map. kpeter@805: /// \tparam CapacityMap The type of the capacity (upper bound) map. kpeter@805: /// \tparam CostMap The type of the cost (length) map. kpeter@805: /// \tparam SupplyMap The type of the supply map. kpeter@805: /// kpeter@805: /// \warning kpeter@805: /// - Arc capacities and costs should be \e non-negative \e integers. kpeter@805: /// - Supply values should be \e signed \e integers. kpeter@805: /// - The value types of the maps should be convertible to each other. kpeter@805: /// - \c CostMap::Value must be signed type. kpeter@805: /// kpeter@805: /// \author Peter Kovacs kpeter@805: template < typename Digraph, kpeter@805: typename LowerMap = typename Digraph::template ArcMap, kpeter@805: typename CapacityMap = typename Digraph::template ArcMap, kpeter@805: typename CostMap = typename Digraph::template ArcMap, kpeter@805: typename SupplyMap = typename Digraph::template NodeMap > kpeter@805: class CapacityScaling kpeter@805: { kpeter@805: TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); kpeter@805: kpeter@805: typedef typename CapacityMap::Value Capacity; kpeter@805: typedef typename CostMap::Value Cost; kpeter@805: typedef typename SupplyMap::Value Supply; kpeter@805: typedef typename Digraph::template ArcMap CapacityArcMap; kpeter@805: typedef typename Digraph::template NodeMap SupplyNodeMap; kpeter@805: typedef typename Digraph::template NodeMap PredMap; kpeter@805: kpeter@805: public: kpeter@805: kpeter@805: /// The type of the flow map. kpeter@805: typedef typename Digraph::template ArcMap FlowMap; kpeter@805: /// The type of the potential map. kpeter@805: typedef typename Digraph::template NodeMap PotentialMap; kpeter@805: kpeter@805: private: kpeter@805: kpeter@805: /// \brief Special implementation of the \ref Dijkstra algorithm kpeter@805: /// for finding shortest paths in the residual network. kpeter@805: /// kpeter@805: /// \ref ResidualDijkstra is a special implementation of the kpeter@805: /// \ref Dijkstra algorithm for finding shortest paths in the kpeter@805: /// residual network of the digraph with respect to the reduced arc kpeter@805: /// costs and modifying the node potentials according to the kpeter@805: /// distance of the nodes. kpeter@805: class ResidualDijkstra kpeter@805: { kpeter@805: typedef typename Digraph::template NodeMap HeapCrossRef; kpeter@805: typedef BinHeap Heap; kpeter@805: kpeter@805: private: kpeter@805: kpeter@805: // The digraph the algorithm runs on kpeter@805: const Digraph &_graph; kpeter@805: kpeter@805: // The main maps kpeter@805: const FlowMap &_flow; kpeter@805: const CapacityArcMap &_res_cap; kpeter@805: const CostMap &_cost; kpeter@805: const SupplyNodeMap &_excess; kpeter@805: PotentialMap &_potential; kpeter@805: kpeter@805: // The distance map kpeter@805: PotentialMap _dist; kpeter@805: // The pred arc map kpeter@805: PredMap &_pred; kpeter@805: // The processed (i.e. permanently labeled) nodes kpeter@805: std::vector _proc_nodes; kpeter@805: kpeter@805: public: kpeter@805: kpeter@805: /// Constructor. kpeter@805: ResidualDijkstra( const Digraph &digraph, kpeter@805: const FlowMap &flow, kpeter@805: const CapacityArcMap &res_cap, kpeter@805: const CostMap &cost, kpeter@805: const SupplyMap &excess, kpeter@805: PotentialMap &potential, kpeter@805: PredMap &pred ) : kpeter@805: _graph(digraph), _flow(flow), _res_cap(res_cap), _cost(cost), kpeter@805: _excess(excess), _potential(potential), _dist(digraph), kpeter@805: _pred(pred) kpeter@805: {} kpeter@805: kpeter@805: /// Run the algorithm from the given source node. kpeter@805: Node run(Node s, Capacity delta = 1) { kpeter@805: HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP); kpeter@805: Heap heap(heap_cross_ref); kpeter@805: heap.push(s, 0); kpeter@805: _pred[s] = INVALID; kpeter@805: _proc_nodes.clear(); kpeter@805: kpeter@805: // Processing nodes kpeter@805: while (!heap.empty() && _excess[heap.top()] > -delta) { kpeter@805: Node u = heap.top(), v; kpeter@805: Cost d = heap.prio() + _potential[u], nd; kpeter@805: _dist[u] = heap.prio(); kpeter@805: heap.pop(); kpeter@805: _proc_nodes.push_back(u); kpeter@805: kpeter@805: // Traversing outgoing arcs kpeter@805: for (OutArcIt e(_graph, u); e != INVALID; ++e) { kpeter@805: if (_res_cap[e] >= delta) { kpeter@805: v = _graph.target(e); kpeter@805: switch(heap.state(v)) { kpeter@805: case Heap::PRE_HEAP: kpeter@805: heap.push(v, d + _cost[e] - _potential[v]); kpeter@805: _pred[v] = e; kpeter@805: break; kpeter@805: case Heap::IN_HEAP: kpeter@805: nd = d + _cost[e] - _potential[v]; kpeter@805: if (nd < heap[v]) { kpeter@805: heap.decrease(v, nd); kpeter@805: _pred[v] = e; kpeter@805: } kpeter@805: break; kpeter@805: case Heap::POST_HEAP: kpeter@805: break; kpeter@805: } kpeter@805: } kpeter@805: } kpeter@805: kpeter@805: // Traversing incoming arcs kpeter@805: for (InArcIt e(_graph, u); e != INVALID; ++e) { kpeter@805: if (_flow[e] >= delta) { kpeter@805: v = _graph.source(e); kpeter@805: switch(heap.state(v)) { kpeter@805: case Heap::PRE_HEAP: kpeter@805: heap.push(v, d - _cost[e] - _potential[v]); kpeter@805: _pred[v] = e; kpeter@805: break; kpeter@805: case Heap::IN_HEAP: kpeter@805: nd = d - _cost[e] - _potential[v]; kpeter@805: if (nd < heap[v]) { kpeter@805: heap.decrease(v, nd); kpeter@805: _pred[v] = e; kpeter@805: } kpeter@805: break; kpeter@805: case Heap::POST_HEAP: kpeter@805: break; kpeter@805: } kpeter@805: } kpeter@805: } kpeter@805: } kpeter@805: if (heap.empty()) return INVALID; kpeter@805: kpeter@805: // Updating potentials of processed nodes kpeter@805: Node t = heap.top(); kpeter@805: Cost t_dist = heap.prio(); kpeter@805: for (int i = 0; i < int(_proc_nodes.size()); ++i) kpeter@805: _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist; kpeter@805: kpeter@805: return t; kpeter@805: } kpeter@805: kpeter@805: }; //class ResidualDijkstra kpeter@805: kpeter@805: private: kpeter@805: kpeter@805: // The digraph the algorithm runs on kpeter@805: const Digraph &_graph; kpeter@805: // The original lower bound map kpeter@805: const LowerMap *_lower; kpeter@805: // The modified capacity map kpeter@805: CapacityArcMap _capacity; kpeter@805: // The original cost map kpeter@805: const CostMap &_cost; kpeter@805: // The modified supply map kpeter@805: SupplyNodeMap _supply; kpeter@805: bool _valid_supply; kpeter@805: kpeter@805: // Arc map of the current flow kpeter@805: FlowMap *_flow; kpeter@805: bool _local_flow; kpeter@805: // Node map of the current potentials kpeter@805: PotentialMap *_potential; kpeter@805: bool _local_potential; kpeter@805: kpeter@805: // The residual capacity map kpeter@805: CapacityArcMap _res_cap; kpeter@805: // The excess map kpeter@805: SupplyNodeMap _excess; kpeter@805: // The excess nodes (i.e. nodes with positive excess) kpeter@805: std::vector _excess_nodes; kpeter@805: // The deficit nodes (i.e. nodes with negative excess) kpeter@805: std::vector _deficit_nodes; kpeter@805: kpeter@805: // The delta parameter used for capacity scaling kpeter@805: Capacity _delta; kpeter@805: // The maximum number of phases kpeter@805: int _phase_num; kpeter@805: kpeter@805: // The pred arc map kpeter@805: PredMap _pred; kpeter@805: // Implementation of the Dijkstra algorithm for finding augmenting kpeter@805: // shortest paths in the residual network kpeter@805: ResidualDijkstra *_dijkstra; kpeter@805: kpeter@805: public: kpeter@805: kpeter@805: /// \brief General constructor (with lower bounds). kpeter@805: /// kpeter@805: /// General constructor (with lower bounds). kpeter@805: /// kpeter@805: /// \param digraph The digraph the algorithm runs on. kpeter@805: /// \param lower The lower bounds of the arcs. kpeter@805: /// \param capacity The capacities (upper bounds) of the arcs. kpeter@805: /// \param cost The cost (length) values of the arcs. kpeter@805: /// \param supply The supply values of the nodes (signed). kpeter@805: CapacityScaling( const Digraph &digraph, kpeter@805: const LowerMap &lower, kpeter@805: const CapacityMap &capacity, kpeter@805: const CostMap &cost, kpeter@805: const SupplyMap &supply ) : kpeter@805: _graph(digraph), _lower(&lower), _capacity(digraph), _cost(cost), kpeter@805: _supply(digraph), _flow(NULL), _local_flow(false), kpeter@805: _potential(NULL), _local_potential(false), kpeter@805: _res_cap(digraph), _excess(digraph), _pred(digraph), _dijkstra(NULL) kpeter@805: { kpeter@805: Supply sum = 0; kpeter@805: for (NodeIt n(_graph); n != INVALID; ++n) { kpeter@805: _supply[n] = supply[n]; kpeter@805: _excess[n] = supply[n]; kpeter@805: sum += supply[n]; kpeter@805: } kpeter@805: _valid_supply = sum == 0; kpeter@805: for (ArcIt a(_graph); a != INVALID; ++a) { kpeter@805: _capacity[a] = capacity[a]; kpeter@805: _res_cap[a] = capacity[a]; kpeter@805: } kpeter@805: kpeter@805: // Remove non-zero lower bounds kpeter@805: typename LowerMap::Value lcap; kpeter@805: for (ArcIt e(_graph); e != INVALID; ++e) { kpeter@805: if ((lcap = lower[e]) != 0) { kpeter@805: _capacity[e] -= lcap; kpeter@805: _res_cap[e] -= lcap; kpeter@805: _supply[_graph.source(e)] -= lcap; kpeter@805: _supply[_graph.target(e)] += lcap; kpeter@805: _excess[_graph.source(e)] -= lcap; kpeter@805: _excess[_graph.target(e)] += lcap; kpeter@805: } kpeter@805: } kpeter@805: } kpeter@805: /* kpeter@805: /// \brief General constructor (without lower bounds). kpeter@805: /// kpeter@805: /// General constructor (without lower bounds). kpeter@805: /// kpeter@805: /// \param digraph The digraph the algorithm runs on. kpeter@805: /// \param capacity The capacities (upper bounds) of the arcs. kpeter@805: /// \param cost The cost (length) values of the arcs. kpeter@805: /// \param supply The supply values of the nodes (signed). kpeter@805: CapacityScaling( const Digraph &digraph, kpeter@805: const CapacityMap &capacity, kpeter@805: const CostMap &cost, kpeter@805: const SupplyMap &supply ) : kpeter@805: _graph(digraph), _lower(NULL), _capacity(capacity), _cost(cost), kpeter@805: _supply(supply), _flow(NULL), _local_flow(false), kpeter@805: _potential(NULL), _local_potential(false), kpeter@805: _res_cap(capacity), _excess(supply), _pred(digraph), _dijkstra(NULL) kpeter@805: { kpeter@805: // Check the sum of supply values kpeter@805: Supply sum = 0; kpeter@805: for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n]; kpeter@805: _valid_supply = sum == 0; kpeter@805: } kpeter@805: kpeter@805: /// \brief Simple constructor (with lower bounds). kpeter@805: /// kpeter@805: /// Simple constructor (with lower bounds). kpeter@805: /// kpeter@805: /// \param digraph The digraph the algorithm runs on. kpeter@805: /// \param lower The lower bounds of the arcs. kpeter@805: /// \param capacity The capacities (upper bounds) of the arcs. kpeter@805: /// \param cost The cost (length) values of the arcs. kpeter@805: /// \param s The source node. kpeter@805: /// \param t The target node. kpeter@805: /// \param flow_value The required amount of flow from node \c s kpeter@805: /// to node \c t (i.e. the supply of \c s and the demand of \c t). kpeter@805: CapacityScaling( const Digraph &digraph, kpeter@805: const LowerMap &lower, kpeter@805: const CapacityMap &capacity, kpeter@805: const CostMap &cost, kpeter@805: Node s, Node t, kpeter@805: Supply flow_value ) : kpeter@805: _graph(digraph), _lower(&lower), _capacity(capacity), _cost(cost), kpeter@805: _supply(digraph, 0), _flow(NULL), _local_flow(false), kpeter@805: _potential(NULL), _local_potential(false), kpeter@805: _res_cap(capacity), _excess(digraph, 0), _pred(digraph), _dijkstra(NULL) kpeter@805: { kpeter@805: // Remove non-zero lower bounds kpeter@805: _supply[s] = _excess[s] = flow_value; kpeter@805: _supply[t] = _excess[t] = -flow_value; kpeter@805: typename LowerMap::Value lcap; kpeter@805: for (ArcIt e(_graph); e != INVALID; ++e) { kpeter@805: if ((lcap = lower[e]) != 0) { kpeter@805: _capacity[e] -= lcap; kpeter@805: _res_cap[e] -= lcap; kpeter@805: _supply[_graph.source(e)] -= lcap; kpeter@805: _supply[_graph.target(e)] += lcap; kpeter@805: _excess[_graph.source(e)] -= lcap; kpeter@805: _excess[_graph.target(e)] += lcap; kpeter@805: } kpeter@805: } kpeter@805: _valid_supply = true; kpeter@805: } kpeter@805: kpeter@805: /// \brief Simple constructor (without lower bounds). kpeter@805: /// kpeter@805: /// Simple constructor (without lower bounds). kpeter@805: /// kpeter@805: /// \param digraph The digraph the algorithm runs on. kpeter@805: /// \param capacity The capacities (upper bounds) of the arcs. kpeter@805: /// \param cost The cost (length) values of the arcs. kpeter@805: /// \param s The source node. kpeter@805: /// \param t The target node. kpeter@805: /// \param flow_value The required amount of flow from node \c s kpeter@805: /// to node \c t (i.e. the supply of \c s and the demand of \c t). kpeter@805: CapacityScaling( const Digraph &digraph, kpeter@805: const CapacityMap &capacity, kpeter@805: const CostMap &cost, kpeter@805: Node s, Node t, kpeter@805: Supply flow_value ) : kpeter@805: _graph(digraph), _lower(NULL), _capacity(capacity), _cost(cost), kpeter@805: _supply(digraph, 0), _flow(NULL), _local_flow(false), kpeter@805: _potential(NULL), _local_potential(false), kpeter@805: _res_cap(capacity), _excess(digraph, 0), _pred(digraph), _dijkstra(NULL) kpeter@805: { kpeter@805: _supply[s] = _excess[s] = flow_value; kpeter@805: _supply[t] = _excess[t] = -flow_value; kpeter@805: _valid_supply = true; kpeter@805: } kpeter@805: */ kpeter@805: /// Destructor. kpeter@805: ~CapacityScaling() { kpeter@805: if (_local_flow) delete _flow; kpeter@805: if (_local_potential) delete _potential; kpeter@805: delete _dijkstra; kpeter@805: } kpeter@805: kpeter@805: /// \brief Set the flow map. kpeter@805: /// kpeter@805: /// Set the flow map. kpeter@805: /// kpeter@805: /// \return \c (*this) kpeter@805: CapacityScaling& flowMap(FlowMap &map) { kpeter@805: if (_local_flow) { kpeter@805: delete _flow; kpeter@805: _local_flow = false; kpeter@805: } kpeter@805: _flow = ↦ kpeter@805: return *this; kpeter@805: } kpeter@805: kpeter@805: /// \brief Set the potential map. kpeter@805: /// kpeter@805: /// Set the potential map. kpeter@805: /// kpeter@805: /// \return \c (*this) kpeter@805: CapacityScaling& potentialMap(PotentialMap &map) { kpeter@805: if (_local_potential) { kpeter@805: delete _potential; kpeter@805: _local_potential = false; kpeter@805: } kpeter@805: _potential = ↦ kpeter@805: return *this; kpeter@805: } kpeter@805: kpeter@805: /// \name Execution control kpeter@805: kpeter@805: /// @{ kpeter@805: kpeter@805: /// \brief Run the algorithm. kpeter@805: /// kpeter@805: /// This function runs the algorithm. kpeter@805: /// kpeter@805: /// \param scaling Enable or disable capacity scaling. kpeter@805: /// If the maximum arc capacity and/or the amount of total supply kpeter@805: /// is rather small, the algorithm could be slightly faster without kpeter@805: /// scaling. kpeter@805: /// kpeter@805: /// \return \c true if a feasible flow can be found. kpeter@805: bool run(bool scaling = true) { kpeter@805: return init(scaling) && start(); kpeter@805: } kpeter@805: kpeter@805: /// @} kpeter@805: kpeter@805: /// \name Query Functions kpeter@805: /// The results of the algorithm can be obtained using these kpeter@805: /// functions.\n kpeter@805: /// \ref lemon::CapacityScaling::run() "run()" must be called before kpeter@805: /// using them. kpeter@805: kpeter@805: /// @{ kpeter@805: kpeter@805: /// \brief Return a const reference to the arc map storing the kpeter@805: /// found flow. kpeter@805: /// kpeter@805: /// Return a const reference to the arc map storing the found flow. kpeter@805: /// kpeter@805: /// \pre \ref run() must be called before using this function. kpeter@805: const FlowMap& flowMap() const { kpeter@805: return *_flow; kpeter@805: } kpeter@805: kpeter@805: /// \brief Return a const reference to the node map storing the kpeter@805: /// found potentials (the dual solution). kpeter@805: /// kpeter@805: /// Return a const reference to the node map storing the found kpeter@805: /// potentials (the dual solution). kpeter@805: /// kpeter@805: /// \pre \ref run() must be called before using this function. kpeter@805: const PotentialMap& potentialMap() const { kpeter@805: return *_potential; kpeter@805: } kpeter@805: kpeter@805: /// \brief Return the flow on the given arc. kpeter@805: /// kpeter@805: /// Return the flow on the given arc. kpeter@805: /// kpeter@805: /// \pre \ref run() must be called before using this function. kpeter@805: Capacity flow(const Arc& arc) const { kpeter@805: return (*_flow)[arc]; kpeter@805: } kpeter@805: kpeter@805: /// \brief Return the potential of the given node. kpeter@805: /// kpeter@805: /// Return the potential of the given node. kpeter@805: /// kpeter@805: /// \pre \ref run() must be called before using this function. kpeter@805: Cost potential(const Node& node) const { kpeter@805: return (*_potential)[node]; kpeter@805: } kpeter@805: kpeter@805: /// \brief Return the total cost of the found flow. kpeter@805: /// kpeter@805: /// Return the total cost of the found flow. The complexity of the kpeter@805: /// function is \f$ O(e) \f$. kpeter@805: /// kpeter@805: /// \pre \ref run() must be called before using this function. kpeter@805: Cost totalCost() const { kpeter@805: Cost c = 0; kpeter@805: for (ArcIt e(_graph); e != INVALID; ++e) kpeter@805: c += (*_flow)[e] * _cost[e]; kpeter@805: return c; kpeter@805: } kpeter@805: kpeter@805: /// @} kpeter@805: kpeter@805: private: kpeter@805: kpeter@805: /// Initialize the algorithm. kpeter@805: bool init(bool scaling) { kpeter@805: if (!_valid_supply) return false; kpeter@805: kpeter@805: // Initializing maps kpeter@805: if (!_flow) { kpeter@805: _flow = new FlowMap(_graph); kpeter@805: _local_flow = true; kpeter@805: } kpeter@805: if (!_potential) { kpeter@805: _potential = new PotentialMap(_graph); kpeter@805: _local_potential = true; kpeter@805: } kpeter@805: for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0; kpeter@805: for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0; kpeter@805: kpeter@805: _dijkstra = new ResidualDijkstra( _graph, *_flow, _res_cap, _cost, kpeter@805: _excess, *_potential, _pred ); kpeter@805: kpeter@805: // Initializing delta value kpeter@805: if (scaling) { kpeter@805: // With scaling kpeter@805: Supply max_sup = 0, max_dem = 0; kpeter@805: for (NodeIt n(_graph); n != INVALID; ++n) { kpeter@805: if ( _supply[n] > max_sup) max_sup = _supply[n]; kpeter@805: if (-_supply[n] > max_dem) max_dem = -_supply[n]; kpeter@805: } kpeter@805: Capacity max_cap = 0; kpeter@805: for (ArcIt e(_graph); e != INVALID; ++e) { kpeter@805: if (_capacity[e] > max_cap) max_cap = _capacity[e]; kpeter@805: } kpeter@805: max_sup = std::min(std::min(max_sup, max_dem), max_cap); kpeter@805: _phase_num = 0; kpeter@805: for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2) kpeter@805: ++_phase_num; kpeter@805: } else { kpeter@805: // Without scaling kpeter@805: _delta = 1; kpeter@805: } kpeter@805: kpeter@805: return true; kpeter@805: } kpeter@805: kpeter@805: bool start() { kpeter@805: if (_delta > 1) kpeter@805: return startWithScaling(); kpeter@805: else kpeter@805: return startWithoutScaling(); kpeter@805: } kpeter@805: kpeter@805: /// Execute the capacity scaling algorithm. kpeter@805: bool startWithScaling() { kpeter@805: // Processing capacity scaling phases kpeter@805: Node s, t; kpeter@805: int phase_cnt = 0; kpeter@805: int factor = 4; kpeter@805: while (true) { kpeter@805: // Saturating all arcs not satisfying the optimality condition kpeter@805: for (ArcIt e(_graph); e != INVALID; ++e) { kpeter@805: Node u = _graph.source(e), v = _graph.target(e); kpeter@805: Cost c = _cost[e] + (*_potential)[u] - (*_potential)[v]; kpeter@805: if (c < 0 && _res_cap[e] >= _delta) { kpeter@805: _excess[u] -= _res_cap[e]; kpeter@805: _excess[v] += _res_cap[e]; kpeter@805: (*_flow)[e] = _capacity[e]; kpeter@805: _res_cap[e] = 0; kpeter@805: } kpeter@805: else if (c > 0 && (*_flow)[e] >= _delta) { kpeter@805: _excess[u] += (*_flow)[e]; kpeter@805: _excess[v] -= (*_flow)[e]; kpeter@805: (*_flow)[e] = 0; kpeter@805: _res_cap[e] = _capacity[e]; kpeter@805: } kpeter@805: } kpeter@805: kpeter@805: // Finding excess nodes and deficit nodes kpeter@805: _excess_nodes.clear(); kpeter@805: _deficit_nodes.clear(); kpeter@805: for (NodeIt n(_graph); n != INVALID; ++n) { kpeter@805: if (_excess[n] >= _delta) _excess_nodes.push_back(n); kpeter@805: if (_excess[n] <= -_delta) _deficit_nodes.push_back(n); kpeter@805: } kpeter@805: int next_node = 0, next_def_node = 0; kpeter@805: kpeter@805: // Finding augmenting shortest paths kpeter@805: while (next_node < int(_excess_nodes.size())) { kpeter@805: // Checking deficit nodes kpeter@805: if (_delta > 1) { kpeter@805: bool delta_deficit = false; kpeter@805: for ( ; next_def_node < int(_deficit_nodes.size()); kpeter@805: ++next_def_node ) { kpeter@805: if (_excess[_deficit_nodes[next_def_node]] <= -_delta) { kpeter@805: delta_deficit = true; kpeter@805: break; kpeter@805: } kpeter@805: } kpeter@805: if (!delta_deficit) break; kpeter@805: } kpeter@805: kpeter@805: // Running Dijkstra kpeter@805: s = _excess_nodes[next_node]; kpeter@805: if ((t = _dijkstra->run(s, _delta)) == INVALID) { kpeter@805: if (_delta > 1) { kpeter@805: ++next_node; kpeter@805: continue; kpeter@805: } kpeter@805: return false; kpeter@805: } kpeter@805: kpeter@805: // Augmenting along a shortest path from s to t. kpeter@805: Capacity d = std::min(_excess[s], -_excess[t]); kpeter@805: Node u = t; kpeter@805: Arc e; kpeter@805: if (d > _delta) { kpeter@805: while ((e = _pred[u]) != INVALID) { kpeter@805: Capacity rc; kpeter@805: if (u == _graph.target(e)) { kpeter@805: rc = _res_cap[e]; kpeter@805: u = _graph.source(e); kpeter@805: } else { kpeter@805: rc = (*_flow)[e]; kpeter@805: u = _graph.target(e); kpeter@805: } kpeter@805: if (rc < d) d = rc; kpeter@805: } kpeter@805: } kpeter@805: u = t; kpeter@805: while ((e = _pred[u]) != INVALID) { kpeter@805: if (u == _graph.target(e)) { kpeter@805: (*_flow)[e] += d; kpeter@805: _res_cap[e] -= d; kpeter@805: u = _graph.source(e); kpeter@805: } else { kpeter@805: (*_flow)[e] -= d; kpeter@805: _res_cap[e] += d; kpeter@805: u = _graph.target(e); kpeter@805: } kpeter@805: } kpeter@805: _excess[s] -= d; kpeter@805: _excess[t] += d; kpeter@805: kpeter@805: if (_excess[s] < _delta) ++next_node; kpeter@805: } kpeter@805: kpeter@805: if (_delta == 1) break; kpeter@805: if (++phase_cnt > _phase_num / 4) factor = 2; kpeter@805: _delta = _delta <= factor ? 1 : _delta / factor; kpeter@805: } kpeter@805: kpeter@805: // Handling non-zero lower bounds kpeter@805: if (_lower) { kpeter@805: for (ArcIt e(_graph); e != INVALID; ++e) kpeter@805: (*_flow)[e] += (*_lower)[e]; kpeter@805: } kpeter@805: return true; kpeter@805: } kpeter@805: kpeter@805: /// Execute the successive shortest path algorithm. kpeter@805: bool startWithoutScaling() { kpeter@805: // Finding excess nodes kpeter@805: for (NodeIt n(_graph); n != INVALID; ++n) kpeter@805: if (_excess[n] > 0) _excess_nodes.push_back(n); kpeter@805: if (_excess_nodes.size() == 0) return true; kpeter@805: int next_node = 0; kpeter@805: kpeter@805: // Finding shortest paths kpeter@805: Node s, t; kpeter@805: while ( _excess[_excess_nodes[next_node]] > 0 || kpeter@805: ++next_node < int(_excess_nodes.size()) ) kpeter@805: { kpeter@805: // Running Dijkstra kpeter@805: s = _excess_nodes[next_node]; kpeter@805: if ((t = _dijkstra->run(s)) == INVALID) return false; kpeter@805: kpeter@805: // Augmenting along a shortest path from s to t kpeter@805: Capacity d = std::min(_excess[s], -_excess[t]); kpeter@805: Node u = t; kpeter@805: Arc e; kpeter@805: if (d > 1) { kpeter@805: while ((e = _pred[u]) != INVALID) { kpeter@805: Capacity rc; kpeter@805: if (u == _graph.target(e)) { kpeter@805: rc = _res_cap[e]; kpeter@805: u = _graph.source(e); kpeter@805: } else { kpeter@805: rc = (*_flow)[e]; kpeter@805: u = _graph.target(e); kpeter@805: } kpeter@805: if (rc < d) d = rc; kpeter@805: } kpeter@805: } kpeter@805: u = t; kpeter@805: while ((e = _pred[u]) != INVALID) { kpeter@805: if (u == _graph.target(e)) { kpeter@805: (*_flow)[e] += d; kpeter@805: _res_cap[e] -= d; kpeter@805: u = _graph.source(e); kpeter@805: } else { kpeter@805: (*_flow)[e] -= d; kpeter@805: _res_cap[e] += d; kpeter@805: u = _graph.target(e); kpeter@805: } kpeter@805: } kpeter@805: _excess[s] -= d; kpeter@805: _excess[t] += d; kpeter@805: } kpeter@805: kpeter@805: // Handling non-zero lower bounds kpeter@805: if (_lower) { kpeter@805: for (ArcIt e(_graph); e != INVALID; ++e) kpeter@805: (*_flow)[e] += (*_lower)[e]; kpeter@805: } kpeter@805: return true; kpeter@805: } kpeter@805: kpeter@805: }; //class CapacityScaling kpeter@805: kpeter@805: ///@} kpeter@805: kpeter@805: } //namespace lemon kpeter@805: kpeter@805: #endif //LEMON_CAPACITY_SCALING_H