# HG changeset patch # User athos # Date 1084464018 0 # Node ID 305bd9c56f10fa775fe8242eec712cd9cdf8a474 # Parent 3f3e184252d27ca56761ac258be2ad1e25b76dca Slight modifications. diff -r 3f3e184252d2 -r 305bd9c56f10 src/hugo/mincostflows.h --- a/src/hugo/mincostflows.h Thu May 13 11:25:52 2004 +0000 +++ b/src/hugo/mincostflows.h Thu May 13 16:00:18 2004 +0000 @@ -92,11 +92,6 @@ //To store the potentila (dual variables) typename Graph::template NodeMap potential; - //Container to store found paths - //std::vector< std::vector > paths; - //typedef DirPath DPath; - //DPath paths; - Length total_length; @@ -151,6 +146,11 @@ break; }; + //We have to copy the potential + FOR_EACH_LOC(typename ResGraphType::NodeIt, n, res_graph){ + potential[n] += dijkstra.distMap()[n]; + } + /* { //We have to copy the potential typename ResGraphType::NodeIt n; @@ -158,7 +158,7 @@ potential[n] += dijkstra.distMap()[n]; } } - + */ //Augmenting on the sortest path Node n=t; @@ -225,25 +225,6 @@ return true; } - /* - ///\todo To be implemented later - - ///This function gives back the \c j-th path in argument p. - ///Assumes that \c run() has been run and nothing changed since then. - /// \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. - template - void getPath(DirPath& p, int j){ - p.clear(); - typename DirPath::Builder B(p); - for(typename std::vector::iterator i=paths[j].begin(); - i!=paths[j].end(); ++i ){ - B.pushBack(*i); - } - - B.commit(); - } - - */ }; //class MinCostFlows @@ -251,4 +232,4 @@ } //namespace hugo -#endif //HUGO_MINCOSTFLOW_H +#endif //HUGO_MINCOSTFLOWS_H diff -r 3f3e184252d2 -r 305bd9c56f10 src/work/athos/mincostflow.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/athos/mincostflow.h Thu May 13 16:00:18 2004 +0000 @@ -0,0 +1,245 @@ +// -*- c++ -*- +#ifndef HUGO_MINCOSTFLOW_H +#define HUGO_MINCOSTFLOW_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::MinCostFlow "MinCostFlow" implements + /// an algorithm for solving the following general minimum cost flow problem> + /// + /// + /// + /// \warning It is assumed here that the problem has a feasible solution + /// + /// 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 MinCostFlow { + + typedef typename LengthMap::ValueType Length; + + + typedef typename SupplyMap::ValueType Supply; + + 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 SupplyMap& supply;//supply or demand of nodes + + + //auxiliary variables + + //To store the flow + EdgeIntMap flow; + //To store the potentila (dual variables) + typename Graph::template NodeMap potential; + //To store excess-deficit values + SupplyMap excess; + + + Length total_length; + + + public : + + + MinCostFlow(Graph& _G, LengthMap& _length, SupplyMap& _supply) : G(_G), + length(_length), supply(_supply), 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() { + + //Resetting variables from previous runs + total_length = 0; + + FOR_EACH_LOC(typename Graph::EdgeIt, e, G){ + flow.set(e,0); + } + + //Initial value for delta + Supply delta = 0; + + FOR_EACH_LOC(typename Graph::NodeIt, n, G){ + if (delta < abs(supply[e])){ + delta = abs(supply[e]); + } + excess.set(n,supply[e]); + //Initialize the copy of the Dijkstra potential to zero + potential.set(n,0); + } + + + + //We need a residual graph which is uncapacitated + ResGraphType res_graph(G, 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 MinCostFlow + + ///@} + +} //namespace hugo + +#endif //HUGO_MINCOSTFLOW_H