alpar@899: // -*- c++ -*- alpar@899: #ifndef HUGO_MINCOSTFLOWS_H alpar@899: #define HUGO_MINCOSTFLOWS_H alpar@899: alpar@899: ///\ingroup flowalgs alpar@899: ///\file alpar@899: ///\brief An algorithm for finding a flow of value \c k (for small values of \c k) having minimal total cost alpar@899: alpar@899: alpar@899: #include alpar@899: #include alpar@899: #include alpar@899: #include alpar@899: alpar@899: namespace hugo { alpar@899: alpar@899: /// \addtogroup flowalgs alpar@899: /// @{ alpar@899: alpar@899: ///\brief Implementation of an algorithm for finding a flow of value \c k alpar@899: ///(for small values of \c k) having minimal total cost between 2 nodes alpar@899: /// alpar@899: /// alpar@899: /// The class \ref hugo::MinCostFlow "MinCostFlow" implements alpar@899: /// an algorithm for finding a flow of value \c k alpar@899: /// having minimal total cost alpar@899: /// from a given source node to a given target node in an alpar@899: /// edge-weighted directed graph. To this end, alpar@899: /// the edge-capacities and edge-weitghs have to be nonnegative. alpar@899: /// The edge-capacities should be integers, but the edge-weights can be alpar@899: /// integers, reals or of other comparable numeric type. alpar@899: /// This algorithm is intended to use only for small values of \c k, alpar@899: /// since it is only polynomial in k, alpar@899: /// not in the length of k (which is log k). alpar@899: /// In order to find the minimum cost flow of value \c k it alpar@899: /// finds the minimum cost flow of value \c i for every alpar@899: /// \c i between 0 and \c k. alpar@899: /// alpar@899: ///\param Graph The directed graph type the algorithm runs on. alpar@899: ///\param LengthMap The type of the length map. alpar@899: ///\param CapacityMap The capacity map type. alpar@899: /// alpar@899: ///\author Attila Bernath alpar@899: template alpar@899: class MinCostFlow { alpar@899: alpar@899: typedef typename LengthMap::ValueType Length; alpar@899: alpar@899: //Warning: this should be integer type alpar@899: typedef typename CapacityMap::ValueType Capacity; alpar@899: alpar@899: typedef typename Graph::Node Node; alpar@899: typedef typename Graph::NodeIt NodeIt; alpar@899: typedef typename Graph::Edge Edge; alpar@899: typedef typename Graph::OutEdgeIt OutEdgeIt; alpar@899: typedef typename Graph::template EdgeMap EdgeIntMap; alpar@899: alpar@899: alpar@899: typedef ResGraphWrapper ResGraphType; alpar@899: typedef typename ResGraphType::Edge ResGraphEdge; alpar@899: alpar@899: class ModLengthMap { alpar@899: typedef typename Graph::template NodeMap NodeMap; alpar@899: const ResGraphType& G; alpar@899: const LengthMap &ol; alpar@899: const NodeMap &pot; alpar@899: public : alpar@899: typedef typename LengthMap::KeyType KeyType; alpar@899: typedef typename LengthMap::ValueType ValueType; alpar@899: alpar@899: ValueType operator[](typename ResGraphType::Edge e) const { alpar@899: if (G.forward(e)) alpar@899: return ol[e]-(pot[G.head(e)]-pot[G.tail(e)]); alpar@899: else alpar@899: return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]); alpar@899: } alpar@899: alpar@899: ModLengthMap(const ResGraphType& _G, alpar@899: const LengthMap &o, const NodeMap &p) : alpar@899: G(_G), /*rev(_rev),*/ ol(o), pot(p){}; alpar@899: };//ModLengthMap alpar@899: alpar@899: alpar@899: protected: alpar@899: alpar@899: //Input alpar@899: const Graph& G; alpar@899: const LengthMap& length; alpar@899: const CapacityMap& capacity; alpar@899: alpar@899: alpar@899: //auxiliary variables alpar@899: alpar@899: //To store the flow alpar@899: EdgeIntMap flow; alpar@899: //To store the potential (dual variables) alpar@899: typedef typename Graph::template NodeMap PotentialMap; alpar@899: PotentialMap potential; alpar@899: alpar@899: alpar@899: Length total_length; alpar@899: alpar@899: alpar@899: public : alpar@899: alpar@899: /// The constructor of the class. alpar@899: alpar@899: ///\param _G The directed graph the algorithm runs on. alpar@899: ///\param _length The length (weight or cost) of the edges. alpar@899: ///\param _cap The capacity of the edges. alpar@899: MinCostFlow(Graph& _G, LengthMap& _length, CapacityMap& _cap) : G(_G), alpar@899: length(_length), capacity(_cap), flow(_G), potential(_G){ } alpar@899: alpar@899: alpar@899: ///Runs the algorithm. alpar@899: alpar@899: ///Runs the algorithm. alpar@899: ///Returns k if there is a flow of value at least k edge-disjoint alpar@899: ///from s to t. alpar@899: ///Otherwise it returns the maximum value of a flow from s to t. alpar@899: /// alpar@899: ///\param s The source node. alpar@899: ///\param t The target node. alpar@899: ///\param k The value of the flow we are looking for. alpar@899: /// alpar@899: ///\todo May be it does make sense to be able to start with a nonzero alpar@899: /// feasible primal-dual solution pair as well. alpar@899: int run(Node s, Node t, int k) { alpar@899: alpar@899: //Resetting variables from previous runs alpar@899: total_length = 0; alpar@899: alpar@899: for (typename Graph::EdgeIt e(G); e!=INVALID; ++e) flow.set(e, 0); alpar@899: alpar@899: //Initialize the potential to zero alpar@899: for (typename Graph::NodeIt n(G); n!=INVALID; ++n) potential.set(n, 0); alpar@899: alpar@899: alpar@899: //We need a residual graph alpar@899: ResGraphType res_graph(G, capacity, flow); alpar@899: alpar@899: alpar@899: ModLengthMap mod_length(res_graph, length, potential); alpar@899: alpar@899: Dijkstra dijkstra(res_graph, mod_length); alpar@899: alpar@899: int i; alpar@899: for (i=0; i 0 && fl_e != 0) alpar@899: return false; alpar@899: if (mod_pot < 0 && fl_e != capacity[e]) alpar@899: return false; alpar@899: } alpar@899: } alpar@899: return true; alpar@899: } alpar@899: alpar@899: alpar@899: }; //class MinCostFlow alpar@899: alpar@899: ///@} alpar@899: alpar@899: } //namespace hugo alpar@899: alpar@899: #endif //HUGO_MINCOSTFLOWS_H