alpar@896: // -*- c++ -*- alpar@896: #ifndef HUGO_MINLENGTHPATHS_H alpar@896: #define HUGO_MINLENGTHPATHS_H alpar@896: alpar@896: ///\ingroup flowalgs alpar@896: ///\file alpar@896: ///\brief An algorithm for finding k paths of minimal total length. alpar@896: alpar@896: alpar@896: #include alpar@896: #include alpar@896: #include alpar@896: alpar@896: namespace hugo { alpar@896: alpar@896: /// \addtogroup flowalgs alpar@896: /// @{ alpar@896: alpar@896: ///\brief Implementation of an algorithm for finding k edge-disjoint paths between 2 nodes alpar@896: /// of minimal total length alpar@896: /// alpar@896: /// The class \ref hugo::MinLengthPaths implements alpar@896: /// an algorithm for finding k edge-disjoint paths alpar@896: /// from a given source node to a given target node in an alpar@896: /// edge-weighted directed graph having minimal total weight (length). alpar@896: /// alpar@896: ///\warning Length values should be nonnegative. alpar@896: /// alpar@896: ///\param Graph The directed graph type the algorithm runs on. alpar@896: ///\param LengthMap The type of the length map (values should be nonnegative). alpar@896: /// alpar@896: ///\author Attila Bernath alpar@896: template alpar@896: class MinLengthPaths{ alpar@896: alpar@896: alpar@896: typedef typename LengthMap::ValueType Length; alpar@896: alpar@896: typedef typename Graph::Node Node; alpar@896: typedef typename Graph::NodeIt NodeIt; alpar@896: typedef typename Graph::Edge Edge; alpar@896: typedef typename Graph::OutEdgeIt OutEdgeIt; alpar@896: typedef typename Graph::template EdgeMap EdgeIntMap; alpar@896: alpar@896: typedef ConstMap ConstMap; alpar@896: alpar@896: //Input alpar@896: const Graph& G; alpar@896: alpar@896: //Auxiliary variables alpar@896: //This is the capacity map for the mincostflow problem alpar@896: ConstMap const1map; alpar@896: //This MinCostFlows instance will actually solve the problem alpar@896: MinCostFlows mincost_flow; alpar@896: alpar@896: //Container to store found paths alpar@896: std::vector< std::vector > paths; alpar@896: alpar@896: public : alpar@896: alpar@896: alpar@896: /// The constructor of the class. alpar@896: alpar@896: ///\param _G The directed graph the algorithm runs on. alpar@896: ///\param _length The length (weight or cost) of the edges. alpar@896: MinLengthPaths(Graph& _G, LengthMap& _length) : G(_G), alpar@896: const1map(1), mincost_flow(_G, _length, const1map){} alpar@896: alpar@896: ///Runs the algorithm. alpar@896: alpar@896: ///Runs the algorithm. alpar@896: ///Returns k if there are at least k edge-disjoint paths from s to t. alpar@896: ///Otherwise it returns the number of found edge-disjoint paths from s to t. alpar@896: /// alpar@896: ///\param s The source node. alpar@896: ///\param t The target node. alpar@896: ///\param k How many paths are we looking for? alpar@896: /// alpar@896: int run(Node s, Node t, int k) { alpar@896: alpar@896: int i = mincost_flow.run(s,t,k); alpar@896: alpar@896: alpar@896: //Let's find the paths alpar@896: //We put the paths into stl vectors (as an inner representation). alpar@896: //In the meantime we lose the information stored in 'reversed'. alpar@896: //We suppose the lengths to be positive now. alpar@896: alpar@896: //We don't want to change the flow of mincost_flow, so we make a copy alpar@896: //The name here suggests that the flow has only 0/1 values. alpar@896: EdgeIntMap reversed(G); alpar@896: alpar@896: for(typename Graph::EdgeIt e(G); e!=INVALID; ++e) alpar@896: reversed[e] = mincost_flow.getFlow()[e]; alpar@896: alpar@896: paths.clear(); alpar@896: //total_length=0; alpar@896: paths.resize(k); alpar@896: for (int j=0; j alpar@896: void getPath(Path& p, size_t j){ alpar@896: alpar@896: p.clear(); alpar@896: if (j>paths.size()-1){ alpar@896: return; alpar@896: } alpar@896: typename Path::Builder B(p); alpar@896: for(typename std::vector::iterator i=paths[j].begin(); alpar@896: i!=paths[j].end(); ++i ){ alpar@896: B.pushBack(*i); alpar@896: } alpar@896: alpar@896: B.commit(); alpar@896: } alpar@896: alpar@896: }; //class MinLengthPaths alpar@896: alpar@896: ///@} alpar@896: alpar@896: } //namespace hugo alpar@896: alpar@896: #endif //HUGO_MINLENGTHPATHS_H