diff -r 2d6c8075d9d0 -r 818510fa3d99 src/lemon/suurballe.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lemon/suurballe.h Wed Sep 29 15:30:04 2004 +0000 @@ -0,0 +1,215 @@ +/* -*- C++ -*- + * src/lemon/suurballe.h - Part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Combinatorial Optimization Research Group, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_SUURBALLE_H +#define LEMON_SUURBALLE_H + +///\ingroup flowalgs +///\file +///\brief An algorithm for finding k paths of minimal total length. + + +#include +#include +#include + +namespace lemon { + +/// \addtogroup flowalgs +/// @{ + + ///\brief Implementation of an algorithm for finding k edge-disjoint paths between 2 nodes + /// of minimal total length + /// + /// The class \ref lemon::Suurballe 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). + /// + ///\note It it questionable if it is correct to call this method after + ///%Suurballe for it is just a special case of Edmond's and Karp's algorithm + ///for finding minimum cost flows. In fact, this implementation is just + ///wraps the MinCostFlow algorithms. The paper of both %Suurballe and + ///Edmonds-Karp published in 1972, therefore it is possibly right to + ///state that they are + ///independent results. Most frequently this special case is referred as + ///%Suurballe method in the literature, especially in communication + ///network context. + ///\author Attila Bernath + template + class Suurballe{ + + + 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 MinCostFlow instance will actually solve the problem + MinCostFlow 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. + Suurballe(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 Suurballe + + ///@} + +} //namespace lemon + +#endif //LEMON_SUURBALLE_H