# HG changeset patch # User athos # Date 1083689535 0 # Node ID d9c06ac0b3a3a23236f0d752c3b92e158d93b9c3 # Parent e63a1dda5c685248764116d8bbcb5361fb509f3f Minimum cost flows of small values: algorithm from Andras Frank's lecture notes (approximately) diff -r e63a1dda5c68 -r d9c06ac0b3a3 src/work/athos/mincostflows.h --- a/src/work/athos/mincostflows.h Tue May 04 16:17:17 2004 +0000 +++ b/src/work/athos/mincostflows.h Tue May 04 16:52:15 2004 +0000 @@ -11,7 +11,7 @@ #include #include #include - +#include namespace hugo { @@ -34,12 +34,13 @@ /// where \c M is the value of the maximal flow. /// ///\author Attila Bernath - template + template class MinCostFlows { typedef typename LengthMap::ValueType Length; - 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; @@ -49,8 +50,8 @@ // typedef ConstMap ConstMap; - typedef ResGraphWrapper ResGraphType; - + typedef ResGraphWrapper ResGraphType; + typedef typename ResGraphType::Edge ResGraphEdge; class ModLengthMap { typedef typename ResGraphType::template NodeMap NodeMap; const ResGraphType& G; @@ -68,7 +69,7 @@ return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]); } - ModLengthMap(const ResGraphType& _G, const EdgeIntMap& _rev, + ModLengthMap(const ResGraphType& _G, const LengthMap &o, const NodeMap &p) : G(_G), /*rev(_rev),*/ ol(o), pot(p){}; };//ModLengthMap @@ -78,7 +79,7 @@ //Input const Graph& G; const LengthMap& length; - const EdgeIntMap& capacity; + const CapacityMap& capacity; //auxiliary variables @@ -98,7 +99,7 @@ public : - MinLengthPaths(Graph& _G, LengthMap& _length, EdgeIntMap& _cap) : G(_G), + MinCostFlows(Graph& _G, LengthMap& _length, CapacityMap& _cap) : G(_G), length(_length), capacity(_cap), flow(_G)/*, dijkstra_dist(_G)*/{ } @@ -109,7 +110,13 @@ ///Otherwise it returns the number of found edge-disjoint paths from s to t. 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); + } + //We need a residual graph ResGraphType res_graph(G, capacity, flow); @@ -138,59 +145,36 @@ //Augmenting on the sortest path Node n=t; - Edge e; + ResGraphEdge e; while (n!=s){ e = dijkstra.pred(n); n = dijkstra.predNode(n); - G.augment(e,1); + res_graph.augment(e,1); + //Let's update the total length + if (res_graph.forward(e)) + total_length += length[e]; + else + total_length -= length[e]; } } - /* - ///\TODO To be implemented later - - //Let's find the paths - //We put the paths into stl vectors (as an inner representation). - //In the meantime we lose the information stored in 'reversed'. - //We suppose the lengths to be positive now. - - //Meanwhile we put the total length of the found paths - //in the member variable total_length - paths.clear(); - total_length=0; - paths.resize(k); - for (int j=0; j const1map(1); + std::cout << "Mincostflows algorithm test..." << std::endl; int k=3; - MinCostFlows< ListGraph, ListGraph::EdgeMap > + MinCostFlows< ListGraph, ListGraph::EdgeMap, ConstMap > surb_test(graph, length, const1map); check( surb_test.run(s,t,k) == 2 && surb_test.totalLength() == 46,"Two paths, total length should be 46"); + k=1; + check( surb_test.run(s,t,k) == 1 && surb_test.totalLength() == 19,"One path, total length should be 19"); + + //cout << surb_test.run(s,t,k) << surb_test.totalLength()< DPath; DPath P(graph); @@ -85,7 +90,7 @@ surb_test.getPath(P,0); check(P.length() == 4, "First path should contain 4 edges."); - + */ cout << (passed ? "All tests passed." : "Some of the tests failed!!!") << endl;