Changed to conform to the new iterator style.
2 #ifndef HUGO_MINLENGTHPATHS_H
3 #define HUGO_MINLENGTHPATHS_H
7 ///\brief An algorithm for finding k paths of minimal total length.
10 #include <hugo/maps.h>
12 #include <hugo/mincostflows.h>
16 /// \addtogroup flowalgs
19 ///\brief Implementation of an algorithm for finding k edge-disjoint paths between 2 nodes
20 /// of minimal total length
22 /// The class \ref hugo::MinLengthPaths implements
23 /// an algorithm for finding k edge-disjoint paths
24 /// from a given source node to a given target node in an
25 /// edge-weighted directed graph having minimal total weight (length).
27 ///\warning Length values should be nonnegative.
29 ///\param Graph The directed graph type the algorithm runs on.
30 ///\param LengthMap The type of the length map (values should be nonnegative).
32 ///\author Attila Bernath
33 template <typename Graph, typename LengthMap>
37 typedef typename LengthMap::ValueType Length;
39 typedef typename Graph::Node Node;
40 typedef typename Graph::NodeIt NodeIt;
41 typedef typename Graph::Edge Edge;
42 typedef typename Graph::OutEdgeIt OutEdgeIt;
43 typedef typename Graph::template EdgeMap<int> EdgeIntMap;
45 typedef ConstMap<Edge,int> ConstMap;
51 //This is the capacity map for the mincostflow problem
53 //This MinCostFlows instance will actually solve the problem
54 MinCostFlows<Graph, LengthMap, ConstMap> mincost_flow;
56 //Container to store found paths
57 std::vector< std::vector<Edge> > paths;
62 /// The constructor of the class.
64 ///\param _G The directed graph the algorithm runs on.
65 ///\param _length The length (weight or cost) of the edges.
66 MinLengthPaths(Graph& _G, LengthMap& _length) : G(_G),
67 const1map(1), mincost_flow(_G, _length, const1map){}
69 ///Runs the algorithm.
71 ///Runs the algorithm.
72 ///Returns k if there are at least k edge-disjoint paths from s to t.
73 ///Otherwise it returns the number of found edge-disjoint paths from s to t.
75 ///\param s The source node.
76 ///\param t The target node.
77 ///\param k How many paths are we looking for?
79 int run(Node s, Node t, int k) {
81 int i = mincost_flow.run(s,t,k);
84 //Let's find the paths
85 //We put the paths into stl vectors (as an inner representation).
86 //In the meantime we lose the information stored in 'reversed'.
87 //We suppose the lengths to be positive now.
89 //We don't want to change the flow of mincost_flow, so we make a copy
90 //The name here suggests that the flow has only 0/1 values.
91 EdgeIntMap reversed(G);
93 for(typename Graph::EdgeIt e(G); e!=INVALID; ++e)
94 reversed[e] = mincost_flow.getFlow()[e];
99 for (int j=0; j<i; ++j){
108 while (!reversed[e]){
112 paths[j].push_back(e);
113 //total_length += length[e];
114 reversed[e] = 1-reversed[e];
122 ///Returns the total length of the paths
124 ///This function gives back the total length of the found paths.
125 ///\pre \ref run() must
126 ///be called before using this function.
127 Length totalLength(){
128 return mincost_flow.totalLength();
131 ///Returns the found flow.
133 ///This function returns a const reference to the EdgeMap \c flow.
134 ///\pre \ref run() must
135 ///be called before using this function.
136 const EdgeIntMap &getFlow() const { return mincost_flow.flow;}
138 /// Returns the optimal dual solution
140 ///This function returns a const reference to the NodeMap
141 ///\c potential (the dual solution).
142 /// \pre \ref run() must be called before using this function.
143 const EdgeIntMap &getPotential() const { return mincost_flow.potential;}
145 ///Checks whether the complementary slackness holds.
147 ///This function checks, whether the given solution is optimal.
148 ///It should return true after calling \ref run()
149 ///Currently this function only checks optimality,
150 ///doesn't bother with feasibility
151 ///It is meant for testing purposes.
153 bool checkComplementarySlackness(){
154 return mincost_flow.checkComplementarySlackness();
157 ///Read the found paths.
159 ///This function gives back the \c j-th path in argument p.
160 ///Assumes that \c run() has been run and nothing changed since then.
161 /// \warning It is assumed that \c p is constructed to
162 ///be a path of graph \c G.
163 ///If \c j is not less than the result of previous \c run,
164 ///then the result here will be an empty path (\c j can be 0 as well).
166 ///\param Path The type of the path structure to put the result to (must meet hugo path concept).
167 ///\param p The path to put the result to
168 ///\param j Which path you want to get from the found paths (in a real application you would get the found paths iteratively)
169 template<typename Path>
170 void getPath(Path& p, size_t j){
173 if (j>paths.size()-1){
176 typename Path::Builder B(p);
177 for(typename std::vector<Edge>::iterator i=paths[j].begin();
178 i!=paths[j].end(); ++i ){
185 }; //class MinLengthPaths
191 #endif //HUGO_MINLENGTHPATHS_H