# HG changeset patch # User alpar # Date 1095838377 0 # Node ID 3a98a1aa5a8f4869b8c4559b333d176ed4cf0c71 # Parent b5dee93d7abd5faacc795eede08a6bb5f413aecd - mincostflows.h renamed to min_cost_flows.h - minlengthpaths.h renamed to min_length_paths.h - src/test/old_path_test.cc removed diff -r b5dee93d7abd -r 3a98a1aa5a8f src/hugo/min_cost_flows.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hugo/min_cost_flows.h Wed Sep 22 07:32:57 2004 +0000 @@ -0,0 +1,241 @@ +// -*- c++ -*- +#ifndef HUGO_MINCOSTFLOWS_H +#define HUGO_MINCOSTFLOWS_H + +///\ingroup flowalgs +///\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 + +namespace hugo { + +/// \addtogroup flowalgs +/// @{ + + ///\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 + /// having minimal total cost + /// from a given source node to a given target node in an + /// edge-weighted directed graph. To this end, + /// the edge-capacities and edge-weitghs have to be nonnegative. + /// The edge-capacities should be integers, but the edge-weights can be + /// integers, reals or of other comparable numeric type. + /// This algorithm is intended to use only for small values of \c k, + /// since it is only polynomial in k, + /// not in the length of k (which is log k). + /// In order to find the minimum cost flow of value \c k it + /// finds the minimum cost flow of value \c i for every + /// \c i between 0 and \c k. + /// + ///\param Graph The directed graph type the algorithm runs on. + ///\param LengthMap The type of the length map. + ///\param CapacityMap The capacity map type. + /// + ///\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 ResGraphWrapper ResGraphType; + typedef typename ResGraphType::Edge ResGraphEdge; + + class ModLengthMap { + typedef typename Graph::template NodeMap NodeMap; + const ResGraphType& G; + 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 potential (dual variables) + typedef typename Graph::template NodeMap PotentialMap; + PotentialMap potential; + + + Length total_length; + + + public : + + /// The constructor of the class. + + ///\param _G The directed graph the algorithm runs on. + ///\param _length The length (weight or cost) of the edges. + ///\param _cap The capacity of the edges. + 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 is a flow of value at least k edge-disjoint + ///from s to t. + ///Otherwise it returns the maximum value of a flow from s to t. + /// + ///\param s The source node. + ///\param t The target node. + ///\param k The value of the flow we are looking for. + /// + ///\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 (typename Graph::EdgeIt e(G); e!=INVALID; ++e) flow.set(e, 0); + + //Initialize the potential to zero + for (typename Graph::NodeIt n(G); n!=INVALID; ++n) 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 diff -r b5dee93d7abd -r 3a98a1aa5a8f src/hugo/min_length_paths.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hugo/min_length_paths.h Wed Sep 22 07:32:57 2004 +0000 @@ -0,0 +1,191 @@ +// -*- c++ -*- +#ifndef HUGO_MINLENGTHPATHS_H +#define HUGO_MINLENGTHPATHS_H + +///\ingroup flowalgs +///\file +///\brief An algorithm for finding k paths of minimal total length. + + +#include +#include +#include + +namespace hugo { + +/// \addtogroup flowalgs +/// @{ + + ///\brief Implementation of an algorithm for finding k edge-disjoint paths between 2 nodes + /// of minimal total length + /// + /// The class \ref hugo::MinLengthPaths implements + /// an algorithm for finding k edge-disjoint paths + /// from a given source node to a given target node in an + /// edge-weighted directed graph having minimal total weight (length). + /// + ///\warning Length values should be nonnegative. + /// + ///\param Graph The directed graph type the algorithm runs on. + ///\param LengthMap The type of the length map (values should be nonnegative). + /// + ///\author Attila Bernath + template + class MinLengthPaths{ + + + typedef typename LengthMap::ValueType Length; + + 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; + + //Input + const Graph& G; + + //Auxiliary variables + //This is the capacity map for the mincostflow problem + ConstMap const1map; + //This MinCostFlows instance will actually solve the problem + MinCostFlows mincost_flow; + + //Container to store found paths + std::vector< std::vector > paths; + + public : + + + /// The constructor of the class. + + ///\param _G The directed graph the algorithm runs on. + ///\param _length The length (weight or cost) of the edges. + MinLengthPaths(Graph& _G, LengthMap& _length) : G(_G), + const1map(1), mincost_flow(_G, _length, const1map){} + + ///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. + /// + ///\param s The source node. + ///\param t The target node. + ///\param k How many paths are we looking for? + /// + int run(Node s, Node t, int k) { + + int i = mincost_flow.run(s,t,k); + + + //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. + + //We don't want to change the flow of mincost_flow, so we make a copy + //The name here suggests that the flow has only 0/1 values. + EdgeIntMap reversed(G); + + for(typename Graph::EdgeIt e(G); e!=INVALID; ++e) + reversed[e] = mincost_flow.getFlow()[e]; + + paths.clear(); + //total_length=0; + paths.resize(k); + for (int j=0; j + void getPath(Path& p, size_t j){ + + p.clear(); + if (j>paths.size()-1){ + return; + } + typename Path::Builder B(p); + for(typename std::vector::iterator i=paths[j].begin(); + i!=paths[j].end(); ++i ){ + B.pushBack(*i); + } + + B.commit(); + } + + }; //class MinLengthPaths + + ///@} + +} //namespace hugo + +#endif //HUGO_MINLENGTHPATHS_H diff -r b5dee93d7abd -r 3a98a1aa5a8f src/hugo/mincostflows.h --- a/src/hugo/mincostflows.h Wed Sep 22 07:22:34 2004 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,241 +0,0 @@ -// -*- c++ -*- -#ifndef HUGO_MINCOSTFLOWS_H -#define HUGO_MINCOSTFLOWS_H - -///\ingroup flowalgs -///\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 - -namespace hugo { - -/// \addtogroup flowalgs -/// @{ - - ///\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 - /// having minimal total cost - /// from a given source node to a given target node in an - /// edge-weighted directed graph. To this end, - /// the edge-capacities and edge-weitghs have to be nonnegative. - /// The edge-capacities should be integers, but the edge-weights can be - /// integers, reals or of other comparable numeric type. - /// This algorithm is intended to use only for small values of \c k, - /// since it is only polynomial in k, - /// not in the length of k (which is log k). - /// In order to find the minimum cost flow of value \c k it - /// finds the minimum cost flow of value \c i for every - /// \c i between 0 and \c k. - /// - ///\param Graph The directed graph type the algorithm runs on. - ///\param LengthMap The type of the length map. - ///\param CapacityMap The capacity map type. - /// - ///\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 ResGraphWrapper ResGraphType; - typedef typename ResGraphType::Edge ResGraphEdge; - - class ModLengthMap { - typedef typename Graph::template NodeMap NodeMap; - const ResGraphType& G; - 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 potential (dual variables) - typedef typename Graph::template NodeMap PotentialMap; - PotentialMap potential; - - - Length total_length; - - - public : - - /// The constructor of the class. - - ///\param _G The directed graph the algorithm runs on. - ///\param _length The length (weight or cost) of the edges. - ///\param _cap The capacity of the edges. - 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 is a flow of value at least k edge-disjoint - ///from s to t. - ///Otherwise it returns the maximum value of a flow from s to t. - /// - ///\param s The source node. - ///\param t The target node. - ///\param k The value of the flow we are looking for. - /// - ///\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 (typename Graph::EdgeIt e(G); e!=INVALID; ++e) flow.set(e, 0); - - //Initialize the potential to zero - for (typename Graph::NodeIt n(G); n!=INVALID; ++n) 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 diff -r b5dee93d7abd -r 3a98a1aa5a8f src/hugo/minlengthpaths.h --- a/src/hugo/minlengthpaths.h Wed Sep 22 07:22:34 2004 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ -// -*- c++ -*- -#ifndef HUGO_MINLENGTHPATHS_H -#define HUGO_MINLENGTHPATHS_H - -///\ingroup flowalgs -///\file -///\brief An algorithm for finding k paths of minimal total length. - - -#include -#include -#include - -namespace hugo { - -/// \addtogroup flowalgs -/// @{ - - ///\brief Implementation of an algorithm for finding k edge-disjoint paths between 2 nodes - /// of minimal total length - /// - /// The class \ref hugo::MinLengthPaths implements - /// an algorithm for finding k edge-disjoint paths - /// from a given source node to a given target node in an - /// edge-weighted directed graph having minimal total weight (length). - /// - ///\warning Length values should be nonnegative. - /// - ///\param Graph The directed graph type the algorithm runs on. - ///\param LengthMap The type of the length map (values should be nonnegative). - /// - ///\author Attila Bernath - template - class MinLengthPaths{ - - - typedef typename LengthMap::ValueType Length; - - 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; - - //Input - const Graph& G; - - //Auxiliary variables - //This is the capacity map for the mincostflow problem - ConstMap const1map; - //This MinCostFlows instance will actually solve the problem - MinCostFlows mincost_flow; - - //Container to store found paths - std::vector< std::vector > paths; - - public : - - - /// The constructor of the class. - - ///\param _G The directed graph the algorithm runs on. - ///\param _length The length (weight or cost) of the edges. - MinLengthPaths(Graph& _G, LengthMap& _length) : G(_G), - const1map(1), mincost_flow(_G, _length, const1map){} - - ///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. - /// - ///\param s The source node. - ///\param t The target node. - ///\param k How many paths are we looking for? - /// - int run(Node s, Node t, int k) { - - int i = mincost_flow.run(s,t,k); - - - //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. - - //We don't want to change the flow of mincost_flow, so we make a copy - //The name here suggests that the flow has only 0/1 values. - EdgeIntMap reversed(G); - - for(typename Graph::EdgeIt e(G); e!=INVALID; ++e) - reversed[e] = mincost_flow.getFlow()[e]; - - paths.clear(); - //total_length=0; - paths.resize(k); - for (int j=0; j - void getPath(Path& p, size_t j){ - - p.clear(); - if (j>paths.size()-1){ - return; - } - typename Path::Builder B(p); - for(typename std::vector::iterator i=paths[j].begin(); - i!=paths[j].end(); ++i ){ - B.pushBack(*i); - } - - B.commit(); - } - - }; //class MinLengthPaths - - ///@} - -} //namespace hugo - -#endif //HUGO_MINLENGTHPATHS_H diff -r b5dee93d7abd -r 3a98a1aa5a8f src/test/Makefile.am --- a/src/test/Makefile.am Wed Sep 22 07:22:34 2004 +0000 +++ b/src/test/Makefile.am Wed Sep 22 07:32:57 2004 +0000 @@ -11,8 +11,8 @@ graph_test \ graph_wrapper_test \ kruskal_test \ - mincostflows_test \ - minlengthpaths_test \ + min_cost_flows_test \ + min_length_paths_test \ path_test \ preflow_test \ test_tools_fail \ @@ -30,8 +30,8 @@ graph_test_SOURCES = graph_test.cc graph_wrapper_test_SOURCES = graph_wrapper_test.cc kruskal_test_SOURCES = kruskal_test.cc -mincostflows_test_SOURCES = mincostflows_test.cc -minlengthpaths_test_SOURCES = minlengthpaths_test.cc +min_cost_flows_test_SOURCES = min_cost_flows_test.cc +min_length_paths_test_SOURCES = min_length_paths_test.cc path_test_SOURCES = path_test.cc preflow_test_SOURCES = preflow_test.cc time_measure_test_SOURCES = time_measure_test.cc diff -r b5dee93d7abd -r 3a98a1aa5a8f src/test/min_cost_flows_test.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/min_cost_flows_test.cc Wed Sep 22 07:32:57 2004 +0000 @@ -0,0 +1,107 @@ +#include +#include "test_tools.h" +#include +#include +//#include +//#include + +using namespace std; +using namespace hugo; + + + +bool passed = true; +/* +void check(bool rc, char *msg="") { + passed = passed && rc; + if(!rc) { + std::cerr << "Test failed! ("<< msg << ")" << std::endl; \ + + + } +} +*/ + + +int main() +{ + + typedef ListGraph::Node Node; + typedef ListGraph::Edge Edge; + + ListGraph graph; + + //Ahuja könyv példája + + Node s=graph.addNode(); + Node v1=graph.addNode(); + Node v2=graph.addNode(); + Node v3=graph.addNode(); + Node v4=graph.addNode(); + Node v5=graph.addNode(); + Node t=graph.addNode(); + + Edge s_v1=graph.addEdge(s, v1); + Edge v1_v2=graph.addEdge(v1, v2); + Edge s_v3=graph.addEdge(s, v3); + Edge v2_v4=graph.addEdge(v2, v4); + Edge v2_v5=graph.addEdge(v2, v5); + Edge v3_v5=graph.addEdge(v3, v5); + Edge v4_t=graph.addEdge(v4, t); + Edge v5_t=graph.addEdge(v5, t); + + + ListGraph::EdgeMap length(graph); + + length.set(s_v1, 6); + length.set(v1_v2, 4); + length.set(s_v3, 10); + length.set(v2_v4, 5); + length.set(v2_v5, 1); + length.set(v3_v5, 4); + length.set(v4_t, 8); + length.set(v5_t, 8); + + ListGraph::EdgeMap capacity(graph); + + capacity.set(s_v1, 2); + capacity.set(v1_v2, 2); + capacity.set(s_v3, 1); + capacity.set(v2_v4, 1); + capacity.set(v2_v5, 1); + capacity.set(v3_v5, 1); + capacity.set(v4_t, 1); + capacity.set(v5_t, 2); + + // ConstMap const1map(1); + std::cout << "Mincostflows algorithm test..." << std::endl; + + MinCostFlows< ListGraph, ListGraph::EdgeMap, ListGraph::EdgeMap > + surb_test(graph, length, capacity); + + int k=1; + + check( surb_test.run(s,t,k) == 1 && surb_test.totalLength() == 19,"One path, total length should be 19"); + + check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?"); + + k=2; + + check( surb_test.run(s,t,k) == 2 && surb_test.totalLength() == 41,"Two paths, total length should be 41"); + + check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?"); + + + k=4; + + check( surb_test.run(s,t,k) == 3 && surb_test.totalLength() == 64,"Three paths, total length should be 64"); + + check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?"); + + + cout << (passed ? "All tests passed." : "Some of the tests failed!!!") + << endl; + + return passed ? 0 : 1; + +} diff -r b5dee93d7abd -r 3a98a1aa5a8f src/test/min_length_paths_test.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/min_length_paths_test.cc Wed Sep 22 07:32:57 2004 +0000 @@ -0,0 +1,94 @@ +#include +#include +#include +//#include +#include "test_tools.h" + +using namespace std; +using namespace hugo; + + + +bool passed = true; + + +int main() +{ + + typedef ListGraph::Node Node; + typedef ListGraph::Edge Edge; + + ListGraph graph; + + //Ahuja könyv példája + + Node s=graph.addNode(); + Node v1=graph.addNode(); + Node v2=graph.addNode(); + Node v3=graph.addNode(); + Node v4=graph.addNode(); + Node v5=graph.addNode(); + Node t=graph.addNode(); + + Edge s_v1=graph.addEdge(s, v1); + Edge v1_v2=graph.addEdge(v1, v2); + Edge s_v3=graph.addEdge(s, v3); + Edge v2_v4=graph.addEdge(v2, v4); + Edge v2_v5=graph.addEdge(v2, v5); + Edge v3_v5=graph.addEdge(v3, v5); + Edge v4_t=graph.addEdge(v4, t); + Edge v5_t=graph.addEdge(v5, t); + + + ListGraph::EdgeMap length(graph); + + length.set(s_v1, 6); + length.set(v1_v2, 4); + length.set(s_v3, 10); + length.set(v2_v4, 5); + length.set(v2_v5, 1); + length.set(v3_v5, 5); + length.set(v4_t, 8); + length.set(v5_t, 8); + + std::cout << "Minlengthpaths algorithm test..." << std::endl; + + + int k=3; + MinLengthPaths< ListGraph, ListGraph::EdgeMap > + surb_test(graph, length); + + check( surb_test.run(s,t,k) == 2 && surb_test.totalLength() == 46, + "Two paths, total length should be 46"); + + check( surb_test.checkComplementarySlackness(), + "Complementary slackness conditions are not met."); + + // typedef DirPath DPath; + // DPath P(graph); + + /* + surb_test.getPath(P,0); + check(P.length() == 4, "First path should contain 4 edges."); + cout< -#include "test_tools.h" -#include -#include -//#include -//#include - -using namespace std; -using namespace hugo; - - - -bool passed = true; -/* -void check(bool rc, char *msg="") { - passed = passed && rc; - if(!rc) { - std::cerr << "Test failed! ("<< msg << ")" << std::endl; \ - - - } -} -*/ - - -int main() -{ - - typedef ListGraph::Node Node; - typedef ListGraph::Edge Edge; - - ListGraph graph; - - //Ahuja könyv példája - - Node s=graph.addNode(); - Node v1=graph.addNode(); - Node v2=graph.addNode(); - Node v3=graph.addNode(); - Node v4=graph.addNode(); - Node v5=graph.addNode(); - Node t=graph.addNode(); - - Edge s_v1=graph.addEdge(s, v1); - Edge v1_v2=graph.addEdge(v1, v2); - Edge s_v3=graph.addEdge(s, v3); - Edge v2_v4=graph.addEdge(v2, v4); - Edge v2_v5=graph.addEdge(v2, v5); - Edge v3_v5=graph.addEdge(v3, v5); - Edge v4_t=graph.addEdge(v4, t); - Edge v5_t=graph.addEdge(v5, t); - - - ListGraph::EdgeMap length(graph); - - length.set(s_v1, 6); - length.set(v1_v2, 4); - length.set(s_v3, 10); - length.set(v2_v4, 5); - length.set(v2_v5, 1); - length.set(v3_v5, 4); - length.set(v4_t, 8); - length.set(v5_t, 8); - - ListGraph::EdgeMap capacity(graph); - - capacity.set(s_v1, 2); - capacity.set(v1_v2, 2); - capacity.set(s_v3, 1); - capacity.set(v2_v4, 1); - capacity.set(v2_v5, 1); - capacity.set(v3_v5, 1); - capacity.set(v4_t, 1); - capacity.set(v5_t, 2); - - // ConstMap const1map(1); - std::cout << "Mincostflows algorithm test..." << std::endl; - - MinCostFlows< ListGraph, ListGraph::EdgeMap, ListGraph::EdgeMap > - surb_test(graph, length, capacity); - - int k=1; - - check( surb_test.run(s,t,k) == 1 && surb_test.totalLength() == 19,"One path, total length should be 19"); - - check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?"); - - k=2; - - check( surb_test.run(s,t,k) == 2 && surb_test.totalLength() == 41,"Two paths, total length should be 41"); - - check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?"); - - - k=4; - - check( surb_test.run(s,t,k) == 3 && surb_test.totalLength() == 64,"Three paths, total length should be 64"); - - check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?"); - - - cout << (passed ? "All tests passed." : "Some of the tests failed!!!") - << endl; - - return passed ? 0 : 1; - -} diff -r b5dee93d7abd -r 3a98a1aa5a8f src/test/minlengthpaths_test.cc --- a/src/test/minlengthpaths_test.cc Wed Sep 22 07:22:34 2004 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -#include -#include -#include -//#include -#include "test_tools.h" - -using namespace std; -using namespace hugo; - - - -bool passed = true; - - -int main() -{ - - typedef ListGraph::Node Node; - typedef ListGraph::Edge Edge; - - ListGraph graph; - - //Ahuja könyv példája - - Node s=graph.addNode(); - Node v1=graph.addNode(); - Node v2=graph.addNode(); - Node v3=graph.addNode(); - Node v4=graph.addNode(); - Node v5=graph.addNode(); - Node t=graph.addNode(); - - Edge s_v1=graph.addEdge(s, v1); - Edge v1_v2=graph.addEdge(v1, v2); - Edge s_v3=graph.addEdge(s, v3); - Edge v2_v4=graph.addEdge(v2, v4); - Edge v2_v5=graph.addEdge(v2, v5); - Edge v3_v5=graph.addEdge(v3, v5); - Edge v4_t=graph.addEdge(v4, t); - Edge v5_t=graph.addEdge(v5, t); - - - ListGraph::EdgeMap length(graph); - - length.set(s_v1, 6); - length.set(v1_v2, 4); - length.set(s_v3, 10); - length.set(v2_v4, 5); - length.set(v2_v5, 1); - length.set(v3_v5, 5); - length.set(v4_t, 8); - length.set(v5_t, 8); - - std::cout << "Minlengthpaths algorithm test..." << std::endl; - - - int k=3; - MinLengthPaths< ListGraph, ListGraph::EdgeMap > - surb_test(graph, length); - - check( surb_test.run(s,t,k) == 2 && surb_test.totalLength() == 46, - "Two paths, total length should be 46"); - - check( surb_test.checkComplementarySlackness(), - "Complementary slackness conditions are not met."); - - // typedef DirPath DPath; - // DPath P(graph); - - /* - surb_test.getPath(P,0); - check(P.length() == 4, "First path should contain 4 edges."); - cout< -#include -//#include -#include -#include - -using namespace std; -using namespace hugo; -#ifdef HUGO_SKELETON_PATH_H -using namespace skeleton; -#endif - -bool passed = true; - -void check(bool rc) { - passed = passed && rc; - if(!rc) { - cout << "Test failed!" << endl; - } -} - -#ifdef DEBUG -const bool debug = true; -#else -const bool debug = false; -#endif - - -int main() { - - try { - - typedef ListGraph::Node Node; - typedef ListGraph::Edge Edge; - - ListGraph G; - - Node s=G.addNode(); - Node v1=G.addNode(); - Node v2=G.addNode(); - Node v3=G.addNode(); - Node v4=G.addNode(); - Node t=G.addNode(); - - Edge e1 = G.addEdge(s, v1); - Edge e2 = G.addEdge(s, v2); - Edge e3 = G.addEdge(v1, v2); - Edge e4 = G.addEdge(v2, v1); - Edge e5 = G.addEdge(v1, v3); - Edge e6 = G.addEdge(v3, v2); - Edge e7 = G.addEdge(v2, v4); - Edge e8 = G.addEdge(v4, v3); - Edge e9 = G.addEdge(v3, t); - Edge e10 = G.addEdge(v4, t); - -#ifdef DEBUG - bool rc; -#endif - - { - cout << "\n\n\nDirPath tesztelese...\n"; - - - cout << "Ures path letrehozasa" << endl; - -#ifndef HUGO_SKELETON_PATH_H - typedef DirPath DPath; -#else - typedef Path DPath; -#endif - - DPath P(G); - - cout << "P.length() == " << P.length() << endl; - check(P.length() == 0); - - cout << "P.tail() valid? " << (P.tail()!=INVALID) << endl; - check(! (P.tail()!=INVALID)); - { - cout << "Builder objektum letrehozasa" << endl; - DPath::Builder B(P); - - cout << "Hozzaadunk az elejehez ket elet..." << endl; - B.pushFront(e6); - B.pushFront(e5); - cout << "P.length() == " << P.length() << endl; - check(P.length() == 0); - - cout << "Commitolunk..." << endl; - B.commit(); - - cout << "P.length() == " << P.length() << endl; - check(P.length() == 2); - - cout << "P.tail() valid? " << (P.tail()!=INVALID) << endl; - check(P.tail()!=INVALID); - cout << "P.tail()==v1 ? " << (P.tail()==v1) << endl; - check(P.tail() == v1); - - // Na ja, ez igy nem igazi, mindket esetet le kene tesztelni, - // de legalabb valami: -#ifdef DEBUG - cout << "Hozzaadunk az elejehez egy nem illeszkedo elet..." << endl; - rc = false; - try { - B.pushFront(e3); - } - catch(const Exception &e) { - cout << "E: " << e.what() << endl; - rc = true; - } - check(rc); -#endif - - cout << "Hozzaadunk a vegehez ket elet..." << endl; - B.pushBack(e7); - B.pushBack(e8); - cout << "P.length() == " << P.length() << endl; - check(P.length() == 2); - - cout << "Es commitolunk...\n"; - B.commit(); - } - cout << "P.length() == " << P.length() << endl; - check(P.length() == 4); - - cout << "P.head()==v3 ? " << (P.head()==v3) << endl; - check(P.head() == v3); - -#ifndef HUGO_SKELETON_PATH_H - cout << "Vegigiteralunk az eleken." << endl; - typedef DPath::NodeIt NodeIt; - typedef DPath::EdgeIt EdgeIt; - EdgeIt e; - int i=1; - for(P.first(e); e!=INVALID; ++e, ++i) { - cout << i << ". el: " <