alpar@956: /* -*- mode: C++; indent-tabs-mode: nil; -*- kpeter@871: * alpar@956: * This file is a part of LEMON, a generic C++ optimization library. kpeter@871: * alpar@1270: * Copyright (C) 2003-2013 kpeter@871: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport kpeter@871: * (Egervary Research Group on Combinatorial Optimization, EGRES). kpeter@871: * kpeter@871: * Permission to use, modify and distribute this software is granted kpeter@871: * provided that this copyright notice appears in all copies. For kpeter@871: * precise terms see the accompanying LICENSE file. kpeter@871: * kpeter@871: * This software is provided "AS IS" with no warranty of any kind, kpeter@871: * express or implied, and with no claim as to its suitability for any kpeter@871: * purpose. kpeter@871: * kpeter@871: */ kpeter@871: kpeter@871: #ifndef LEMON_CAPACITY_SCALING_H kpeter@871: #define LEMON_CAPACITY_SCALING_H kpeter@871: kpeter@872: /// \ingroup min_cost_flow_algs kpeter@871: /// kpeter@871: /// \file kpeter@872: /// \brief Capacity Scaling algorithm for finding a minimum cost flow. kpeter@871: kpeter@871: #include kpeter@872: #include kpeter@872: #include kpeter@1362: #include kpeter@871: #include kpeter@871: kpeter@871: namespace lemon { kpeter@871: kpeter@873: /// \brief Default traits class of CapacityScaling algorithm. kpeter@873: /// kpeter@873: /// Default traits class of CapacityScaling algorithm. kpeter@873: /// \tparam GR Digraph type. kpeter@878: /// \tparam V The number type used for flow amounts, capacity bounds kpeter@873: /// and supply values. By default it is \c int. kpeter@878: /// \tparam C The number type used for costs and potentials. kpeter@873: /// By default it is the same as \c V. kpeter@873: template kpeter@873: struct CapacityScalingDefaultTraits kpeter@873: { kpeter@873: /// The type of the digraph kpeter@873: typedef GR Digraph; kpeter@873: /// The type of the flow amounts, capacity bounds and supply values kpeter@873: typedef V Value; kpeter@873: /// The type of the arc costs kpeter@873: typedef C Cost; kpeter@873: kpeter@873: /// \brief The type of the heap used for internal Dijkstra computations. kpeter@873: /// kpeter@873: /// The type of the heap used for internal Dijkstra computations. kpeter@873: /// It must conform to the \ref lemon::concepts::Heap "Heap" concept, kpeter@873: /// its priority type must be \c Cost and its cross reference type kpeter@873: /// must be \ref RangeMap "RangeMap". kpeter@873: typedef BinHeap > Heap; kpeter@873: }; kpeter@873: kpeter@872: /// \addtogroup min_cost_flow_algs kpeter@871: /// @{ kpeter@871: kpeter@872: /// \brief Implementation of the Capacity Scaling algorithm for kpeter@872: /// finding a \ref min_cost_flow "minimum cost flow". kpeter@871: /// kpeter@871: /// \ref CapacityScaling implements the capacity scaling version kpeter@872: /// of the successive shortest path algorithm for finding a alpar@1221: /// \ref min_cost_flow "minimum cost flow" \cite amo93networkflows, alpar@1221: /// \cite edmondskarp72theoretical. It is an efficient dual kpeter@1217: /// solution method, which runs in polynomial time kpeter@1254: /// \f$O(m\log U (n+m)\log n)\f$, where U denotes the maximum kpeter@1217: /// of node supply and arc capacity values. kpeter@887: /// kpeter@1165: /// This algorithm is typically slower than \ref CostScaling and kpeter@1165: /// \ref NetworkSimplex, but in special cases, it can be more kpeter@1165: /// efficient than them. kpeter@1165: /// (For more information, see \ref min_cost_flow_algs "the module page".) kpeter@871: /// kpeter@872: /// Most of the parameters of the problem (except for the digraph) kpeter@872: /// can be given using separate functions, and the algorithm can be kpeter@872: /// executed using the \ref run() function. If some parameters are not kpeter@872: /// specified, then default values will be used. kpeter@871: /// kpeter@872: /// \tparam GR The digraph type the algorithm runs on. kpeter@878: /// \tparam V The number type used for flow amounts, capacity bounds kpeter@891: /// and supply values in the algorithm. By default, it is \c int. kpeter@878: /// \tparam C The number type used for costs and potentials in the kpeter@891: /// algorithm. By default, it is the same as \c V. kpeter@891: /// \tparam TR The traits class that defines various types used by the kpeter@891: /// algorithm. By default, it is \ref CapacityScalingDefaultTraits kpeter@891: /// "CapacityScalingDefaultTraits". kpeter@891: /// In most cases, this parameter should not be set directly, kpeter@891: /// consider to use the named template parameters instead. kpeter@871: /// kpeter@1025: /// \warning Both \c V and \c C must be signed number types. kpeter@1137: /// \warning Capacity bounds and supply values must be integer, but kpeter@1137: /// arc costs can be arbitrary real numbers. kpeter@1023: /// \warning This algorithm does not support negative costs for kpeter@1023: /// arcs having infinite upper bound. kpeter@873: #ifdef DOXYGEN kpeter@873: template kpeter@873: #else kpeter@873: template < typename GR, typename V = int, typename C = V, kpeter@873: typename TR = CapacityScalingDefaultTraits > kpeter@873: #endif kpeter@871: class CapacityScaling kpeter@871: { kpeter@872: public: kpeter@871: kpeter@873: /// The type of the digraph kpeter@873: typedef typename TR::Digraph Digraph; kpeter@872: /// The type of the flow amounts, capacity bounds and supply values kpeter@873: typedef typename TR::Value Value; kpeter@872: /// The type of the arc costs kpeter@873: typedef typename TR::Cost Cost; kpeter@873: kpeter@873: /// The type of the heap used for internal Dijkstra computations kpeter@873: typedef typename TR::Heap Heap; kpeter@873: alpar@1250: /// \brief The \ref lemon::CapacityScalingDefaultTraits "traits class" alpar@1250: /// of the algorithm kpeter@873: typedef TR Traits; kpeter@871: kpeter@871: public: kpeter@871: kpeter@872: /// \brief Problem type constants for the \c run() function. kpeter@872: /// kpeter@872: /// Enum type containing the problem type constants that can be kpeter@872: /// returned by the \ref run() function of the algorithm. kpeter@872: enum ProblemType { kpeter@872: /// The problem has no feasible solution (flow). kpeter@872: INFEASIBLE, kpeter@872: /// The problem has optimal solution (i.e. it is feasible and kpeter@872: /// bounded), and the algorithm has found optimal flow and node kpeter@872: /// potentials (primal and dual solutions). kpeter@872: OPTIMAL, kpeter@872: /// The digraph contains an arc of negative cost and infinite kpeter@872: /// upper bound. It means that the objective function is unbounded kpeter@878: /// on that arc, however, note that it could actually be bounded kpeter@872: /// over the feasible flows, but this algroithm cannot handle kpeter@872: /// these cases. kpeter@872: UNBOUNDED kpeter@872: }; alpar@956: kpeter@872: private: kpeter@872: kpeter@872: TEMPLATE_DIGRAPH_TYPEDEFS(GR); kpeter@872: kpeter@872: typedef std::vector IntVector; kpeter@872: typedef std::vector ValueVector; kpeter@872: typedef std::vector CostVector; kpeter@910: typedef std::vector BoolVector; kpeter@910: // Note: vector is used instead of vector for efficiency reasons kpeter@871: kpeter@871: private: kpeter@871: kpeter@872: // Data related to the underlying digraph kpeter@872: const GR &_graph; kpeter@872: int _node_num; kpeter@872: int _arc_num; kpeter@872: int _res_arc_num; kpeter@872: int _root; kpeter@872: kpeter@872: // Parameters of the problem kpeter@1297: bool _has_lower; kpeter@872: Value _sum_supply; kpeter@872: kpeter@872: // Data structures for storing the digraph kpeter@872: IntNodeMap _node_id; kpeter@872: IntArcMap _arc_idf; kpeter@872: IntArcMap _arc_idb; kpeter@872: IntVector _first_out; kpeter@872: BoolVector _forward; kpeter@872: IntVector _source; kpeter@872: IntVector _target; kpeter@872: IntVector _reverse; kpeter@872: kpeter@872: // Node and arc data kpeter@872: ValueVector _lower; kpeter@872: ValueVector _upper; kpeter@872: CostVector _cost; kpeter@872: ValueVector _supply; kpeter@872: kpeter@872: ValueVector _res_cap; kpeter@872: CostVector _pi; kpeter@872: ValueVector _excess; kpeter@872: IntVector _excess_nodes; kpeter@872: IntVector _deficit_nodes; kpeter@872: kpeter@872: Value _delta; kpeter@876: int _factor; kpeter@872: IntVector _pred; kpeter@872: kpeter@872: public: alpar@956: kpeter@872: /// \brief Constant for infinite upper bounds (capacities). kpeter@871: /// kpeter@872: /// Constant for infinite upper bounds (capacities). kpeter@872: /// It is \c std::numeric_limits::infinity() if available, kpeter@872: /// \c std::numeric_limits::max() otherwise. kpeter@872: const Value INF; kpeter@872: kpeter@872: private: kpeter@872: kpeter@872: // Special implementation of the Dijkstra algorithm for finding kpeter@872: // shortest paths in the residual network of the digraph with kpeter@872: // respect to the reduced arc costs and modifying the node kpeter@872: // potentials according to the found distance labels. kpeter@871: class ResidualDijkstra kpeter@871: { kpeter@871: private: kpeter@871: kpeter@872: int _node_num; kpeter@877: bool _geq; kpeter@872: const IntVector &_first_out; kpeter@872: const IntVector &_target; kpeter@872: const CostVector &_cost; kpeter@872: const ValueVector &_res_cap; kpeter@872: const ValueVector &_excess; kpeter@872: CostVector &_pi; kpeter@872: IntVector &_pred; alpar@956: kpeter@872: IntVector _proc_nodes; kpeter@872: CostVector _dist; alpar@956: kpeter@871: public: kpeter@871: kpeter@872: ResidualDijkstra(CapacityScaling& cs) : kpeter@877: _node_num(cs._node_num), _geq(cs._sum_supply < 0), kpeter@877: _first_out(cs._first_out), _target(cs._target), _cost(cs._cost), kpeter@877: _res_cap(cs._res_cap), _excess(cs._excess), _pi(cs._pi), kpeter@877: _pred(cs._pred), _dist(cs._node_num) kpeter@871: {} kpeter@871: kpeter@872: int run(int s, Value delta = 1) { kpeter@873: RangeMap heap_cross_ref(_node_num, Heap::PRE_HEAP); kpeter@871: Heap heap(heap_cross_ref); kpeter@871: heap.push(s, 0); kpeter@872: _pred[s] = -1; kpeter@871: _proc_nodes.clear(); kpeter@871: kpeter@872: // Process nodes kpeter@871: while (!heap.empty() && _excess[heap.top()] > -delta) { kpeter@872: int u = heap.top(), v; kpeter@872: Cost d = heap.prio() + _pi[u], dn; kpeter@871: _dist[u] = heap.prio(); kpeter@872: _proc_nodes.push_back(u); kpeter@871: heap.pop(); kpeter@871: kpeter@872: // Traverse outgoing residual arcs kpeter@877: int last_out = _geq ? _first_out[u+1] : _first_out[u+1] - 1; kpeter@877: for (int a = _first_out[u]; a != last_out; ++a) { kpeter@872: if (_res_cap[a] < delta) continue; kpeter@872: v = _target[a]; kpeter@872: switch (heap.state(v)) { kpeter@871: case Heap::PRE_HEAP: kpeter@872: heap.push(v, d + _cost[a] - _pi[v]); kpeter@872: _pred[v] = a; kpeter@871: break; kpeter@871: case Heap::IN_HEAP: kpeter@872: dn = d + _cost[a] - _pi[v]; kpeter@872: if (dn < heap[v]) { kpeter@872: heap.decrease(v, dn); kpeter@872: _pred[v] = a; kpeter@871: } kpeter@871: break; kpeter@871: case Heap::POST_HEAP: kpeter@871: break; kpeter@871: } kpeter@871: } kpeter@871: } kpeter@872: if (heap.empty()) return -1; kpeter@871: kpeter@872: // Update potentials of processed nodes kpeter@872: int t = heap.top(); kpeter@872: Cost dt = heap.prio(); kpeter@872: for (int i = 0; i < int(_proc_nodes.size()); ++i) { kpeter@872: _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - dt; kpeter@872: } kpeter@871: kpeter@871: return t; kpeter@871: } kpeter@871: kpeter@871: }; //class ResidualDijkstra kpeter@871: kpeter@871: public: kpeter@871: kpeter@873: /// \name Named Template Parameters kpeter@873: /// @{ kpeter@873: kpeter@873: template kpeter@873: struct SetHeapTraits : public Traits { kpeter@873: typedef T Heap; kpeter@873: }; kpeter@873: kpeter@873: /// \brief \ref named-templ-param "Named parameter" for setting kpeter@873: /// \c Heap type. kpeter@873: /// kpeter@873: /// \ref named-templ-param "Named parameter" for setting \c Heap kpeter@873: /// type, which is used for internal Dijkstra computations. kpeter@873: /// It must conform to the \ref lemon::concepts::Heap "Heap" concept, kpeter@873: /// its priority type must be \c Cost and its cross reference type kpeter@873: /// must be \ref RangeMap "RangeMap". kpeter@873: template kpeter@873: struct SetHeap kpeter@873: : public CapacityScaling > { kpeter@873: typedef CapacityScaling > Create; kpeter@873: }; kpeter@873: kpeter@873: /// @} kpeter@873: kpeter@941: protected: kpeter@941: kpeter@941: CapacityScaling() {} kpeter@941: kpeter@873: public: kpeter@873: kpeter@872: /// \brief Constructor. kpeter@871: /// kpeter@872: /// The constructor of the class. kpeter@871: /// kpeter@872: /// \param graph The digraph the algorithm runs on. kpeter@872: CapacityScaling(const GR& graph) : kpeter@872: _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph), kpeter@872: INF(std::numeric_limits::has_infinity ? kpeter@872: std::numeric_limits::infinity() : kpeter@872: std::numeric_limits::max()) kpeter@871: { kpeter@878: // Check the number types kpeter@872: LEMON_ASSERT(std::numeric_limits::is_signed, kpeter@872: "The flow type of CapacityScaling must be signed"); kpeter@872: LEMON_ASSERT(std::numeric_limits::is_signed, kpeter@872: "The cost type of CapacityScaling must be signed"); kpeter@872: kpeter@898: // Reset data structures kpeter@872: reset(); kpeter@871: } kpeter@871: kpeter@872: /// \name Parameters kpeter@872: /// The parameters of the algorithm can be specified using these kpeter@872: /// functions. kpeter@872: kpeter@872: /// @{ kpeter@872: kpeter@872: /// \brief Set the lower bounds on the arcs. kpeter@871: /// kpeter@872: /// This function sets the lower bounds on the arcs. kpeter@872: /// If it is not used before calling \ref run(), the lower bounds kpeter@872: /// will be set to zero on all arcs. kpeter@871: /// kpeter@872: /// \param map An arc map storing the lower bounds. kpeter@872: /// Its \c Value type must be convertible to the \c Value type kpeter@872: /// of the algorithm. kpeter@872: /// kpeter@872: /// \return (*this) kpeter@872: template kpeter@872: CapacityScaling& lowerMap(const LowerMap& map) { kpeter@1297: _has_lower = true; kpeter@872: for (ArcIt a(_graph); a != INVALID; ++a) { kpeter@872: _lower[_arc_idf[a]] = map[a]; kpeter@871: } kpeter@871: return *this; kpeter@871: } kpeter@871: kpeter@872: /// \brief Set the upper bounds (capacities) on the arcs. kpeter@871: /// kpeter@872: /// This function sets the upper bounds (capacities) on the arcs. kpeter@872: /// If it is not used before calling \ref run(), the upper bounds kpeter@872: /// will be set to \ref INF on all arcs (i.e. the flow value will be kpeter@878: /// unbounded from above). kpeter@871: /// kpeter@872: /// \param map An arc map storing the upper bounds. kpeter@872: /// Its \c Value type must be convertible to the \c Value type kpeter@872: /// of the algorithm. kpeter@872: /// kpeter@872: /// \return (*this) kpeter@872: template kpeter@872: CapacityScaling& upperMap(const UpperMap& map) { kpeter@872: for (ArcIt a(_graph); a != INVALID; ++a) { kpeter@872: _upper[_arc_idf[a]] = map[a]; kpeter@871: } kpeter@871: return *this; kpeter@871: } kpeter@871: kpeter@872: /// \brief Set the costs of the arcs. kpeter@872: /// kpeter@872: /// This function sets the costs of the arcs. kpeter@872: /// If it is not used before calling \ref run(), the costs kpeter@872: /// will be set to \c 1 on all arcs. kpeter@872: /// kpeter@872: /// \param map An arc map storing the costs. kpeter@872: /// Its \c Value type must be convertible to the \c Cost type kpeter@872: /// of the algorithm. kpeter@872: /// kpeter@872: /// \return (*this) kpeter@872: template kpeter@872: CapacityScaling& costMap(const CostMap& map) { kpeter@872: for (ArcIt a(_graph); a != INVALID; ++a) { kpeter@872: _cost[_arc_idf[a]] = map[a]; kpeter@872: _cost[_arc_idb[a]] = -map[a]; kpeter@872: } kpeter@872: return *this; kpeter@872: } kpeter@872: kpeter@872: /// \brief Set the supply values of the nodes. kpeter@872: /// kpeter@872: /// This function sets the supply values of the nodes. kpeter@872: /// If neither this function nor \ref stSupply() is used before kpeter@872: /// calling \ref run(), the supply of each node will be set to zero. kpeter@872: /// kpeter@872: /// \param map A node map storing the supply values. kpeter@872: /// Its \c Value type must be convertible to the \c Value type kpeter@872: /// of the algorithm. kpeter@872: /// kpeter@872: /// \return (*this) kpeter@872: template kpeter@872: CapacityScaling& supplyMap(const SupplyMap& map) { kpeter@872: for (NodeIt n(_graph); n != INVALID; ++n) { kpeter@872: _supply[_node_id[n]] = map[n]; kpeter@872: } kpeter@872: return *this; kpeter@872: } kpeter@872: kpeter@872: /// \brief Set single source and target nodes and a supply value. kpeter@872: /// kpeter@872: /// This function sets a single source node and a single target node kpeter@872: /// and the required flow value. kpeter@872: /// If neither this function nor \ref supplyMap() is used before kpeter@872: /// calling \ref run(), the supply of each node will be set to zero. kpeter@872: /// kpeter@872: /// Using this function has the same effect as using \ref supplyMap() kpeter@1023: /// with a map in which \c k is assigned to \c s, \c -k is kpeter@872: /// assigned to \c t and all other nodes have zero supply value. kpeter@872: /// kpeter@872: /// \param s The source node. kpeter@872: /// \param t The target node. kpeter@872: /// \param k The required amount of flow from node \c s to node \c t kpeter@872: /// (i.e. the supply of \c s and the demand of \c t). kpeter@872: /// kpeter@872: /// \return (*this) kpeter@872: CapacityScaling& stSupply(const Node& s, const Node& t, Value k) { kpeter@872: for (int i = 0; i != _node_num; ++i) { kpeter@872: _supply[i] = 0; kpeter@872: } kpeter@872: _supply[_node_id[s]] = k; kpeter@872: _supply[_node_id[t]] = -k; kpeter@872: return *this; kpeter@872: } alpar@956: kpeter@872: /// @} kpeter@872: kpeter@871: /// \name Execution control kpeter@873: /// The algorithm can be executed using \ref run(). kpeter@871: kpeter@871: /// @{ kpeter@871: kpeter@871: /// \brief Run the algorithm. kpeter@871: /// kpeter@871: /// This function runs the algorithm. kpeter@872: /// The paramters can be specified using functions \ref lowerMap(), kpeter@872: /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). kpeter@872: /// For example, kpeter@872: /// \code kpeter@872: /// CapacityScaling cs(graph); kpeter@872: /// cs.lowerMap(lower).upperMap(upper).costMap(cost) kpeter@872: /// .supplyMap(sup).run(); kpeter@872: /// \endcode kpeter@872: /// kpeter@898: /// This function can be called more than once. All the given parameters kpeter@898: /// are kept for the next call, unless \ref resetParams() or \ref reset() kpeter@898: /// is used, thus only the modified parameters have to be set again. kpeter@898: /// If the underlying digraph was also modified after the construction kpeter@898: /// of the class (or the last \ref reset() call), then the \ref reset() kpeter@898: /// function must be called. kpeter@871: /// kpeter@876: /// \param factor The capacity scaling factor. It must be larger than kpeter@876: /// one to use scaling. If it is less or equal to one, then scaling kpeter@876: /// will be disabled. kpeter@871: /// kpeter@872: /// \return \c INFEASIBLE if no feasible flow exists, kpeter@872: /// \n \c OPTIMAL if the problem has optimal solution kpeter@872: /// (i.e. it is feasible and bounded), and the algorithm has found kpeter@872: /// optimal flow and node potentials (primal and dual solutions), kpeter@872: /// \n \c UNBOUNDED if the digraph contains an arc of negative cost kpeter@872: /// and infinite upper bound. It means that the objective function kpeter@878: /// is unbounded on that arc, however, note that it could actually be kpeter@872: /// bounded over the feasible flows, but this algroithm cannot handle kpeter@872: /// these cases. kpeter@872: /// kpeter@872: /// \see ProblemType kpeter@898: /// \see resetParams(), reset() kpeter@876: ProblemType run(int factor = 4) { kpeter@876: _factor = factor; kpeter@876: ProblemType pt = init(); kpeter@872: if (pt != OPTIMAL) return pt; kpeter@872: return start(); kpeter@872: } kpeter@872: kpeter@872: /// \brief Reset all the parameters that have been given before. kpeter@872: /// kpeter@872: /// This function resets all the paramaters that have been given kpeter@872: /// before using functions \ref lowerMap(), \ref upperMap(), kpeter@872: /// \ref costMap(), \ref supplyMap(), \ref stSupply(). kpeter@872: /// kpeter@898: /// It is useful for multiple \ref run() calls. Basically, all the given kpeter@898: /// parameters are kept for the next \ref run() call, unless kpeter@898: /// \ref resetParams() or \ref reset() is used. kpeter@898: /// If the underlying digraph was also modified after the construction kpeter@898: /// of the class or the last \ref reset() call, then the \ref reset() kpeter@898: /// function must be used, otherwise \ref resetParams() is sufficient. kpeter@872: /// kpeter@872: /// For example, kpeter@872: /// \code kpeter@872: /// CapacityScaling cs(graph); kpeter@872: /// kpeter@872: /// // First run kpeter@872: /// cs.lowerMap(lower).upperMap(upper).costMap(cost) kpeter@872: /// .supplyMap(sup).run(); kpeter@872: /// kpeter@898: /// // Run again with modified cost map (resetParams() is not called, kpeter@872: /// // so only the cost map have to be set again) kpeter@872: /// cost[e] += 100; kpeter@872: /// cs.costMap(cost).run(); kpeter@872: /// kpeter@898: /// // Run again from scratch using resetParams() kpeter@872: /// // (the lower bounds will be set to zero on all arcs) kpeter@898: /// cs.resetParams(); kpeter@872: /// cs.upperMap(capacity).costMap(cost) kpeter@872: /// .supplyMap(sup).run(); kpeter@872: /// \endcode kpeter@872: /// kpeter@872: /// \return (*this) kpeter@898: /// kpeter@898: /// \see reset(), run() kpeter@898: CapacityScaling& resetParams() { kpeter@872: for (int i = 0; i != _node_num; ++i) { kpeter@872: _supply[i] = 0; kpeter@872: } kpeter@872: for (int j = 0; j != _res_arc_num; ++j) { kpeter@872: _lower[j] = 0; kpeter@872: _upper[j] = INF; kpeter@872: _cost[j] = _forward[j] ? 1 : -1; kpeter@872: } kpeter@1297: _has_lower = false; kpeter@887: return *this; kpeter@887: } kpeter@887: kpeter@898: /// \brief Reset the internal data structures and all the parameters kpeter@898: /// that have been given before. kpeter@898: /// kpeter@898: /// This function resets the internal data structures and all the kpeter@898: /// paramaters that have been given before using functions \ref lowerMap(), kpeter@898: /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). kpeter@898: /// kpeter@898: /// It is useful for multiple \ref run() calls. Basically, all the given kpeter@898: /// parameters are kept for the next \ref run() call, unless kpeter@898: /// \ref resetParams() or \ref reset() is used. kpeter@898: /// If the underlying digraph was also modified after the construction kpeter@898: /// of the class or the last \ref reset() call, then the \ref reset() kpeter@898: /// function must be used, otherwise \ref resetParams() is sufficient. kpeter@898: /// kpeter@898: /// See \ref resetParams() for examples. kpeter@898: /// kpeter@898: /// \return (*this) kpeter@898: /// kpeter@898: /// \see resetParams(), run() kpeter@898: CapacityScaling& reset() { kpeter@898: // Resize vectors kpeter@898: _node_num = countNodes(_graph); kpeter@898: _arc_num = countArcs(_graph); kpeter@898: _res_arc_num = 2 * (_arc_num + _node_num); kpeter@898: _root = _node_num; kpeter@898: ++_node_num; kpeter@898: kpeter@898: _first_out.resize(_node_num + 1); kpeter@898: _forward.resize(_res_arc_num); kpeter@898: _source.resize(_res_arc_num); kpeter@898: _target.resize(_res_arc_num); kpeter@898: _reverse.resize(_res_arc_num); kpeter@898: kpeter@898: _lower.resize(_res_arc_num); kpeter@898: _upper.resize(_res_arc_num); kpeter@898: _cost.resize(_res_arc_num); kpeter@898: _supply.resize(_node_num); alpar@956: kpeter@898: _res_cap.resize(_res_arc_num); kpeter@898: _pi.resize(_node_num); kpeter@898: _excess.resize(_node_num); kpeter@898: _pred.resize(_node_num); kpeter@898: kpeter@898: // Copy the graph kpeter@898: int i = 0, j = 0, k = 2 * _arc_num + _node_num - 1; kpeter@898: for (NodeIt n(_graph); n != INVALID; ++n, ++i) { kpeter@898: _node_id[n] = i; kpeter@898: } kpeter@898: i = 0; kpeter@898: for (NodeIt n(_graph); n != INVALID; ++n, ++i) { kpeter@898: _first_out[i] = j; kpeter@898: for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) { kpeter@898: _arc_idf[a] = j; kpeter@898: _forward[j] = true; kpeter@898: _source[j] = i; kpeter@898: _target[j] = _node_id[_graph.runningNode(a)]; kpeter@898: } kpeter@898: for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) { kpeter@898: _arc_idb[a] = j; kpeter@898: _forward[j] = false; kpeter@898: _source[j] = i; kpeter@898: _target[j] = _node_id[_graph.runningNode(a)]; kpeter@898: } kpeter@898: _forward[j] = false; kpeter@898: _source[j] = i; kpeter@898: _target[j] = _root; kpeter@898: _reverse[j] = k; kpeter@898: _forward[k] = true; kpeter@898: _source[k] = _root; kpeter@898: _target[k] = i; kpeter@898: _reverse[k] = j; kpeter@898: ++j; ++k; kpeter@898: } kpeter@898: _first_out[i] = j; kpeter@898: _first_out[_node_num] = k; kpeter@898: for (ArcIt a(_graph); a != INVALID; ++a) { kpeter@898: int fi = _arc_idf[a]; kpeter@898: int bi = _arc_idb[a]; kpeter@898: _reverse[fi] = bi; kpeter@898: _reverse[bi] = fi; kpeter@898: } alpar@956: kpeter@898: // Reset parameters kpeter@898: resetParams(); kpeter@872: return *this; kpeter@871: } kpeter@871: kpeter@871: /// @} kpeter@871: kpeter@871: /// \name Query Functions kpeter@871: /// The results of the algorithm can be obtained using these kpeter@871: /// functions.\n kpeter@872: /// The \ref run() function must be called before using them. kpeter@871: kpeter@871: /// @{ kpeter@871: kpeter@872: /// \brief Return the total cost of the found flow. kpeter@871: /// kpeter@872: /// This function returns the total cost of the found flow. kpeter@1254: /// Its complexity is O(m). kpeter@872: /// kpeter@872: /// \note The return type of the function can be specified as a kpeter@872: /// template parameter. For example, kpeter@872: /// \code kpeter@872: /// cs.totalCost(); kpeter@872: /// \endcode kpeter@872: /// It is useful if the total cost cannot be stored in the \c Cost kpeter@872: /// type of the algorithm, which is the default return type of the kpeter@872: /// function. kpeter@871: /// kpeter@871: /// \pre \ref run() must be called before using this function. kpeter@872: template kpeter@872: Number totalCost() const { kpeter@872: Number c = 0; kpeter@872: for (ArcIt a(_graph); a != INVALID; ++a) { kpeter@872: int i = _arc_idb[a]; kpeter@872: c += static_cast(_res_cap[i]) * kpeter@872: (-static_cast(_cost[i])); kpeter@872: } kpeter@872: return c; kpeter@871: } kpeter@871: kpeter@872: #ifndef DOXYGEN kpeter@872: Cost totalCost() const { kpeter@872: return totalCost(); kpeter@871: } kpeter@872: #endif kpeter@871: kpeter@871: /// \brief Return the flow on the given arc. kpeter@871: /// kpeter@872: /// This function returns the flow on the given arc. kpeter@871: /// kpeter@871: /// \pre \ref run() must be called before using this function. kpeter@872: Value flow(const Arc& a) const { kpeter@872: return _res_cap[_arc_idb[a]]; kpeter@871: } kpeter@871: kpeter@1165: /// \brief Copy the flow values (the primal solution) into the kpeter@1165: /// given map. kpeter@871: /// kpeter@872: /// This function copies the flow value on each arc into the given kpeter@872: /// map. The \c Value type of the algorithm must be convertible to kpeter@872: /// the \c Value type of the map. kpeter@871: /// kpeter@871: /// \pre \ref run() must be called before using this function. kpeter@872: template kpeter@872: void flowMap(FlowMap &map) const { kpeter@872: for (ArcIt a(_graph); a != INVALID; ++a) { kpeter@872: map.set(a, _res_cap[_arc_idb[a]]); kpeter@872: } kpeter@871: } kpeter@871: kpeter@872: /// \brief Return the potential (dual value) of the given node. kpeter@871: /// kpeter@872: /// This function returns the potential (dual value) of the kpeter@872: /// given node. kpeter@871: /// kpeter@871: /// \pre \ref run() must be called before using this function. kpeter@872: Cost potential(const Node& n) const { kpeter@872: return _pi[_node_id[n]]; kpeter@872: } kpeter@872: kpeter@1165: /// \brief Copy the potential values (the dual solution) into the kpeter@1165: /// given map. kpeter@872: /// kpeter@872: /// This function copies the potential (dual value) of each node kpeter@872: /// into the given map. kpeter@872: /// The \c Cost type of the algorithm must be convertible to the kpeter@872: /// \c Value type of the map. kpeter@872: /// kpeter@872: /// \pre \ref run() must be called before using this function. kpeter@872: template kpeter@872: void potentialMap(PotentialMap &map) const { kpeter@872: for (NodeIt n(_graph); n != INVALID; ++n) { kpeter@872: map.set(n, _pi[_node_id[n]]); kpeter@872: } kpeter@871: } kpeter@871: kpeter@871: /// @} kpeter@871: kpeter@871: private: kpeter@871: kpeter@872: // Initialize the algorithm kpeter@876: ProblemType init() { kpeter@887: if (_node_num <= 1) return INFEASIBLE; kpeter@871: kpeter@872: // Check the sum of supply values kpeter@872: _sum_supply = 0; kpeter@872: for (int i = 0; i != _root; ++i) { kpeter@872: _sum_supply += _supply[i]; kpeter@871: } kpeter@872: if (_sum_supply > 0) return INFEASIBLE; alpar@956: kpeter@1240: // Check lower and upper bounds kpeter@1240: LEMON_DEBUG(checkBoundMaps(), kpeter@1240: "Upper bounds must be greater or equal to the lower bounds"); kpeter@1240: kpeter@1240: kpeter@877: // Initialize vectors kpeter@872: for (int i = 0; i != _root; ++i) { kpeter@872: _pi[i] = 0; kpeter@872: _excess[i] = _supply[i]; kpeter@871: } kpeter@871: kpeter@872: // Remove non-zero lower bounds kpeter@877: const Value MAX = std::numeric_limits::max(); kpeter@877: int last_out; kpeter@1297: if (_has_lower) { kpeter@872: for (int i = 0; i != _root; ++i) { kpeter@877: last_out = _first_out[i+1]; kpeter@877: for (int j = _first_out[i]; j != last_out; ++j) { kpeter@872: if (_forward[j]) { kpeter@872: Value c = _lower[j]; kpeter@872: if (c >= 0) { kpeter@877: _res_cap[j] = _upper[j] < MAX ? _upper[j] - c : INF; kpeter@872: } else { kpeter@877: _res_cap[j] = _upper[j] < MAX + c ? _upper[j] - c : INF; kpeter@872: } kpeter@872: _excess[i] -= c; kpeter@872: _excess[_target[j]] += c; kpeter@872: } else { kpeter@872: _res_cap[j] = 0; kpeter@872: } kpeter@872: } kpeter@872: } kpeter@872: } else { kpeter@872: for (int j = 0; j != _res_arc_num; ++j) { kpeter@872: _res_cap[j] = _forward[j] ? _upper[j] : 0; kpeter@872: } kpeter@872: } kpeter@871: kpeter@872: // Handle negative costs kpeter@877: for (int i = 0; i != _root; ++i) { kpeter@877: last_out = _first_out[i+1] - 1; kpeter@877: for (int j = _first_out[i]; j != last_out; ++j) { kpeter@877: Value rc = _res_cap[j]; kpeter@877: if (_cost[j] < 0 && rc > 0) { kpeter@877: if (rc >= MAX) return UNBOUNDED; kpeter@877: _excess[i] -= rc; kpeter@877: _excess[_target[j]] += rc; kpeter@877: _res_cap[j] = 0; kpeter@877: _res_cap[_reverse[j]] += rc; kpeter@872: } kpeter@872: } kpeter@872: } alpar@956: kpeter@872: // Handle GEQ supply type kpeter@872: if (_sum_supply < 0) { kpeter@872: _pi[_root] = 0; kpeter@872: _excess[_root] = -_sum_supply; kpeter@872: for (int a = _first_out[_root]; a != _res_arc_num; ++a) { kpeter@877: int ra = _reverse[a]; kpeter@877: _res_cap[a] = -_sum_supply + 1; kpeter@877: _res_cap[ra] = 0; kpeter@872: _cost[a] = 0; kpeter@877: _cost[ra] = 0; kpeter@872: } kpeter@872: } else { kpeter@872: _pi[_root] = 0; kpeter@872: _excess[_root] = 0; kpeter@872: for (int a = _first_out[_root]; a != _res_arc_num; ++a) { kpeter@877: int ra = _reverse[a]; kpeter@872: _res_cap[a] = 1; kpeter@877: _res_cap[ra] = 0; kpeter@872: _cost[a] = 0; kpeter@877: _cost[ra] = 0; kpeter@872: } kpeter@872: } kpeter@872: kpeter@872: // Initialize delta value kpeter@876: if (_factor > 1) { kpeter@871: // With scaling kpeter@910: Value max_sup = 0, max_dem = 0, max_cap = 0; kpeter@910: for (int i = 0; i != _root; ++i) { kpeter@877: Value ex = _excess[i]; kpeter@877: if ( ex > max_sup) max_sup = ex; kpeter@877: if (-ex > max_dem) max_dem = -ex; kpeter@910: int last_out = _first_out[i+1] - 1; kpeter@910: for (int j = _first_out[i]; j != last_out; ++j) { kpeter@910: if (_res_cap[j] > max_cap) max_cap = _res_cap[j]; kpeter@910: } kpeter@871: } kpeter@871: max_sup = std::min(std::min(max_sup, max_dem), max_cap); kpeter@876: for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2) ; kpeter@871: } else { kpeter@871: // Without scaling kpeter@871: _delta = 1; kpeter@871: } kpeter@871: kpeter@872: return OPTIMAL; kpeter@871: } kpeter@871: kpeter@1296: // Check if the upper bound is greater than or equal to the lower bound kpeter@1296: // on each forward arc. kpeter@1240: bool checkBoundMaps() { kpeter@1240: for (int j = 0; j != _res_arc_num; ++j) { kpeter@1296: if (_forward[j] && _upper[j] < _lower[j]) return false; kpeter@1240: } kpeter@1240: return true; kpeter@1240: } kpeter@887: kpeter@872: ProblemType start() { kpeter@872: // Execute the algorithm kpeter@872: ProblemType pt; kpeter@871: if (_delta > 1) kpeter@872: pt = startWithScaling(); kpeter@871: else kpeter@872: pt = startWithoutScaling(); kpeter@872: kpeter@872: // Handle non-zero lower bounds kpeter@1297: if (_has_lower) { kpeter@877: int limit = _first_out[_root]; kpeter@877: for (int j = 0; j != limit; ++j) { kpeter@1296: if (_forward[j]) _res_cap[_reverse[j]] += _lower[j]; kpeter@872: } kpeter@872: } kpeter@872: kpeter@872: // Shift potentials if necessary kpeter@872: Cost pr = _pi[_root]; kpeter@872: if (_sum_supply < 0 || pr > 0) { kpeter@872: for (int i = 0; i != _node_num; ++i) { kpeter@872: _pi[i] -= pr; alpar@956: } kpeter@872: } alpar@956: kpeter@872: return pt; kpeter@871: } kpeter@871: kpeter@872: // Execute the capacity scaling algorithm kpeter@872: ProblemType startWithScaling() { kpeter@873: // Perform capacity scaling phases kpeter@872: int s, t; kpeter@872: ResidualDijkstra _dijkstra(*this); kpeter@871: while (true) { kpeter@872: // Saturate all arcs not satisfying the optimality condition kpeter@877: int last_out; kpeter@872: for (int u = 0; u != _node_num; ++u) { kpeter@877: last_out = _sum_supply < 0 ? kpeter@877: _first_out[u+1] : _first_out[u+1] - 1; kpeter@877: for (int a = _first_out[u]; a != last_out; ++a) { kpeter@872: int v = _target[a]; kpeter@872: Cost c = _cost[a] + _pi[u] - _pi[v]; kpeter@872: Value rc = _res_cap[a]; kpeter@872: if (c < 0 && rc >= _delta) { kpeter@872: _excess[u] -= rc; kpeter@872: _excess[v] += rc; kpeter@872: _res_cap[a] = 0; kpeter@872: _res_cap[_reverse[a]] += rc; kpeter@872: } kpeter@871: } kpeter@871: } kpeter@871: kpeter@872: // Find excess nodes and deficit nodes kpeter@871: _excess_nodes.clear(); kpeter@871: _deficit_nodes.clear(); kpeter@872: for (int u = 0; u != _node_num; ++u) { kpeter@877: Value ex = _excess[u]; kpeter@877: if (ex >= _delta) _excess_nodes.push_back(u); kpeter@877: if (ex <= -_delta) _deficit_nodes.push_back(u); kpeter@871: } kpeter@871: int next_node = 0, next_def_node = 0; kpeter@871: kpeter@872: // Find augmenting shortest paths kpeter@871: while (next_node < int(_excess_nodes.size())) { kpeter@872: // Check deficit nodes kpeter@871: if (_delta > 1) { kpeter@871: bool delta_deficit = false; kpeter@871: for ( ; next_def_node < int(_deficit_nodes.size()); kpeter@871: ++next_def_node ) { kpeter@871: if (_excess[_deficit_nodes[next_def_node]] <= -_delta) { kpeter@871: delta_deficit = true; kpeter@871: break; kpeter@871: } kpeter@871: } kpeter@871: if (!delta_deficit) break; kpeter@871: } kpeter@871: kpeter@872: // Run Dijkstra in the residual network kpeter@871: s = _excess_nodes[next_node]; kpeter@872: if ((t = _dijkstra.run(s, _delta)) == -1) { kpeter@871: if (_delta > 1) { kpeter@871: ++next_node; kpeter@871: continue; kpeter@871: } kpeter@872: return INFEASIBLE; kpeter@871: } kpeter@871: kpeter@872: // Augment along a shortest path from s to t kpeter@872: Value d = std::min(_excess[s], -_excess[t]); kpeter@872: int u = t; kpeter@872: int a; kpeter@871: if (d > _delta) { kpeter@872: while ((a = _pred[u]) != -1) { kpeter@872: if (_res_cap[a] < d) d = _res_cap[a]; kpeter@872: u = _source[a]; kpeter@871: } kpeter@871: } kpeter@871: u = t; kpeter@872: while ((a = _pred[u]) != -1) { kpeter@872: _res_cap[a] -= d; kpeter@872: _res_cap[_reverse[a]] += d; kpeter@872: u = _source[a]; kpeter@871: } kpeter@871: _excess[s] -= d; kpeter@871: _excess[t] += d; kpeter@871: kpeter@871: if (_excess[s] < _delta) ++next_node; kpeter@871: } kpeter@871: kpeter@871: if (_delta == 1) break; kpeter@876: _delta = _delta <= _factor ? 1 : _delta / _factor; kpeter@871: } kpeter@871: kpeter@872: return OPTIMAL; kpeter@871: } kpeter@871: kpeter@872: // Execute the successive shortest path algorithm kpeter@872: ProblemType startWithoutScaling() { kpeter@872: // Find excess nodes kpeter@872: _excess_nodes.clear(); kpeter@872: for (int i = 0; i != _node_num; ++i) { kpeter@872: if (_excess[i] > 0) _excess_nodes.push_back(i); kpeter@872: } kpeter@872: if (_excess_nodes.size() == 0) return OPTIMAL; kpeter@871: int next_node = 0; kpeter@871: kpeter@872: // Find shortest paths kpeter@872: int s, t; kpeter@872: ResidualDijkstra _dijkstra(*this); kpeter@871: while ( _excess[_excess_nodes[next_node]] > 0 || kpeter@871: ++next_node < int(_excess_nodes.size()) ) kpeter@871: { kpeter@872: // Run Dijkstra in the residual network kpeter@871: s = _excess_nodes[next_node]; kpeter@872: if ((t = _dijkstra.run(s)) == -1) return INFEASIBLE; kpeter@871: kpeter@872: // Augment along a shortest path from s to t kpeter@872: Value d = std::min(_excess[s], -_excess[t]); kpeter@872: int u = t; kpeter@872: int a; kpeter@871: if (d > 1) { kpeter@872: while ((a = _pred[u]) != -1) { kpeter@872: if (_res_cap[a] < d) d = _res_cap[a]; kpeter@872: u = _source[a]; kpeter@871: } kpeter@871: } kpeter@871: u = t; kpeter@872: while ((a = _pred[u]) != -1) { kpeter@872: _res_cap[a] -= d; kpeter@872: _res_cap[_reverse[a]] += d; kpeter@872: u = _source[a]; kpeter@871: } kpeter@871: _excess[s] -= d; kpeter@871: _excess[t] += d; kpeter@871: } kpeter@871: kpeter@872: return OPTIMAL; kpeter@871: } kpeter@871: kpeter@871: }; //class CapacityScaling kpeter@871: kpeter@871: ///@} kpeter@871: kpeter@871: } //namespace lemon kpeter@871: kpeter@871: #endif //LEMON_CAPACITY_SCALING_H