athos@276: // -*- c++ -*- athos@523: #ifndef HUGO_MINCOSTFLOWS_H athos@523: #define HUGO_MINCOSTFLOWS_H athos@276: klao@491: ///\ingroup galgs alpar@294: ///\file athos@523: ///\brief An algorithm for finding a flow of value \c k (for small values of \c k) having minimal total cost alpar@294: athos@276: #include athos@551: #include athos@276: #include athos@551: #include athos@551: #include athos@530: #include athos@306: athos@276: namespace hugo { athos@276: alpar@430: /// \addtogroup galgs alpar@430: /// @{ athos@322: athos@523: ///\brief Implementation of an algorithm for finding a flow of value \c k athos@523: ///(for small values of \c k) having minimal total cost between 2 nodes athos@523: /// klao@310: /// athos@523: /// The class \ref hugo::MinCostFlows "MinCostFlows" implements athos@523: /// an algorithm for finding a flow of value \c k athos@523: ///(for small values of \c k) having minimal total cost klao@310: /// from a given source node to a given target node in an athos@523: /// edge-weighted directed graph having nonnegative integer capacities. athos@523: /// The range of the length (weight) function is nonnegative reals but athos@523: /// the range of capacity function is the set of nonnegative integers. athos@523: /// It is not a polinomial time algorithm for counting the minimum cost athos@523: /// maximal flow, since it counts the minimum cost flow for every value 0..M athos@523: /// where \c M is the value of the maximal flow. alpar@456: /// alpar@456: ///\author Attila Bernath athos@530: template athos@523: class MinCostFlows { athos@276: klao@310: typedef typename LengthMap::ValueType Length; athos@527: athos@530: //Warning: this should be integer type athos@530: typedef typename CapacityMap::ValueType Capacity; athos@511: athos@276: typedef typename Graph::Node Node; athos@276: typedef typename Graph::NodeIt NodeIt; athos@276: typedef typename Graph::Edge Edge; athos@276: typedef typename Graph::OutEdgeIt OutEdgeIt; athos@511: typedef typename Graph::template EdgeMap EdgeIntMap; athos@306: athos@527: // typedef ConstMap ConstMap; athos@306: athos@530: typedef ResGraphWrapper ResGraphType; athos@530: typedef typename ResGraphType::Edge ResGraphEdge; athos@547: athos@306: class ModLengthMap { athos@547: //typedef typename ResGraphType::template NodeMap NodeMap; athos@547: typedef typename Graph::template NodeMap NodeMap; athos@306: const ResGraphType& G; athos@527: // const EdgeIntMap& rev; klao@310: const LengthMap &ol; klao@310: const NodeMap &pot; athos@306: public : athos@306: typedef typename LengthMap::KeyType KeyType; athos@306: typedef typename LengthMap::ValueType ValueType; athos@511: athos@306: ValueType operator[](typename ResGraphType::Edge e) const { athos@527: if (G.forward(e)) athos@527: return ol[e]-(pot[G.head(e)]-pot[G.tail(e)]); athos@527: else athos@527: return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]); athos@306: } athos@511: athos@530: ModLengthMap(const ResGraphType& _G, klao@310: const LengthMap &o, const NodeMap &p) : athos@527: G(_G), /*rev(_rev),*/ ol(o), pot(p){}; athos@511: };//ModLengthMap athos@511: athos@511: athos@306: athos@527: //Input athos@276: const Graph& G; athos@276: const LengthMap& length; athos@530: const CapacityMap& capacity; athos@276: alpar@328: //auxiliary variables athos@322: athos@551: //To store the flow athos@527: EdgeIntMap flow; athos@551: //To store the potentila (dual variables) athos@547: typename Graph::template NodeMap potential; athos@276: athos@322: //Container to store found paths athos@551: //std::vector< std::vector > paths; athos@511: //typedef DirPath DPath; athos@511: //DPath paths; athos@511: athos@511: athos@511: Length total_length; athos@322: athos@276: public : klao@310: athos@276: athos@530: MinCostFlows(Graph& _G, LengthMap& _length, CapacityMap& _cap) : G(_G), athos@547: length(_length), capacity(_cap), flow(_G), potential(_G){ } athos@276: alpar@294: alpar@329: ///Runs the algorithm. alpar@329: alpar@329: ///Runs the algorithm. athos@306: ///Returns k if there are at least k edge-disjoint paths from s to t. alpar@329: ///Otherwise it returns the number of found edge-disjoint paths from s to t. athos@306: int run(Node s, Node t, int k) { athos@276: athos@530: //Resetting variables from previous runs athos@530: total_length = 0; athos@547: athos@530: FOR_EACH_LOC(typename Graph::EdgeIt, e, G){ athos@530: flow.set(e,0); athos@530: } athos@547: athos@547: FOR_EACH_LOC(typename Graph::NodeIt, n, G){ athos@547: //cout << potential[n]< potential(res_graph); athos@547: athos@547: athos@547: ModLengthMap mod_length(res_graph, length, potential); athos@306: athos@306: Dijkstra dijkstra(res_graph, mod_length); athos@322: athos@322: int i; athos@322: for (i=0; i 0 && fl_e != 0) athos@551: return false; athos@551: if (mod_pot < 0 && fl_e != capacity[e]) athos@551: return false; athos@551: } athos@551: } athos@551: return true; athos@551: } athos@551: athos@530: /* athos@530: ///\todo To be implemented later athos@530: athos@511: ///This function gives back the \c j-th path in argument p. athos@511: ///Assumes that \c run() has been run and nothing changed since then. athos@519: /// \warning It is assumed that \c p is constructed to be a path of graph \c G. If \c j is greater than the result of previous \c run, then the result here will be an empty path. athos@511: template athos@511: void getPath(DirPath& p, int j){ athos@511: p.clear(); athos@511: typename DirPath::Builder B(p); athos@511: for(typename std::vector::iterator i=paths[j].begin(); athos@511: i!=paths[j].end(); ++i ){ athos@520: B.pushBack(*i); athos@511: } athos@511: athos@511: B.commit(); athos@511: } athos@276: athos@530: */ athos@530: athos@530: }; //class MinCostFlows athos@276: alpar@430: ///@} athos@276: athos@276: } //namespace hugo athos@276: athos@527: #endif //HUGO_MINCOSTFLOW_H