// -*- c++ -*- #ifndef HUGO_MINCOSTFLOWS_H #define HUGO_MINCOSTFLOWS_H ///\ingroup galgs ///\file ///\brief An algorithm for finding a flow of value \c k (for small values of \c k) having minimal total cost #include #include #include #include #include namespace hugo { /// \addtogroup galgs /// @{ ///\brief Implementation of an algorithm for finding a flow of value \c k ///(for small values of \c k) having minimal total cost between 2 nodes /// /// /// The class \ref hugo::MinCostFlows "MinCostFlows" implements /// an algorithm for finding a flow of value \c k ///(for small values of \c k) having minimal total cost /// from a given source node to a given target node in an /// edge-weighted directed graph having nonnegative integer capacities. /// The range of the length (weight) function is nonnegative reals but /// the range of capacity function is the set of nonnegative integers. /// It is not a polinomial time algorithm for counting the minimum cost /// maximal flow, since it counts the minimum cost flow for every value 0..M /// where \c M is the value of the maximal flow. /// ///\author Attila Bernath template class MinCostFlows { typedef typename LengthMap::ValueType Length; //Warning: this should be integer type typedef typename CapacityMap::ValueType Capacity; typedef typename Graph::Node Node; typedef typename Graph::NodeIt NodeIt; typedef typename Graph::Edge Edge; typedef typename Graph::OutEdgeIt OutEdgeIt; typedef typename Graph::template EdgeMap EdgeIntMap; // typedef ConstMap ConstMap; typedef ResGraphWrapper ResGraphType; typedef typename ResGraphType::Edge ResGraphEdge; class ModLengthMap { //typedef typename ResGraphType::template NodeMap NodeMap; typedef typename Graph::template NodeMap NodeMap; const ResGraphType& G; // const EdgeIntMap& rev; const LengthMap &ol; const NodeMap &pot; public : typedef typename LengthMap::KeyType KeyType; typedef typename LengthMap::ValueType ValueType; ValueType operator[](typename ResGraphType::Edge e) const { if (G.forward(e)) return ol[e]-(pot[G.head(e)]-pot[G.tail(e)]); else return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]); } ModLengthMap(const ResGraphType& _G, const LengthMap &o, const NodeMap &p) : G(_G), /*rev(_rev),*/ ol(o), pot(p){}; };//ModLengthMap protected: //Input const Graph& G; const LengthMap& length; const CapacityMap& capacity; //auxiliary variables //To store the flow EdgeIntMap flow; //To store the potentila (dual variables) typedef typename Graph::template NodeMap PotentialMap; PotentialMap potential; Length total_length; public : MinCostFlows(Graph& _G, LengthMap& _length, CapacityMap& _cap) : G(_G), length(_length), capacity(_cap), flow(_G), potential(_G){ } ///Runs the algorithm. ///Runs the algorithm. ///Returns k if there are at least k edge-disjoint paths from s to t. ///Otherwise it returns the number of found edge-disjoint paths from s to t. ///\todo May be it does make sense to be able to start with a nonzero /// feasible primal-dual solution pair as well. int run(Node s, Node t, int k) { //Resetting variables from previous runs total_length = 0; FOR_EACH_LOC(typename Graph::EdgeIt, e, G){ flow.set(e,0); } //Initialize the potential to zero FOR_EACH_LOC(typename Graph::NodeIt, n, G){ potential.set(n,0); } //We need a residual graph ResGraphType res_graph(G, capacity, flow); ModLengthMap mod_length(res_graph, length, potential); Dijkstra dijkstra(res_graph, mod_length); int i; for (i=0; i 0 && fl_e != 0) return false; if (mod_pot < 0 && fl_e != capacity[e]) return false; } } return true; } }; //class MinCostFlows ///@} } //namespace hugo #endif //HUGO_MINCOSTFLOWS_H