/* -*- C++ -*-
*
* This file is a part of LEMON, a generic C++ optimization library
*
* Copyright (C) 2003-2007
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
* (Egervary Research Group on Combinatorial Optimization, 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 shortest_path
///\file
///\brief An algorithm for finding k paths of minimal total length.
#include
#include
#include
#include
namespace lemon {
/// \addtogroup shortest_path
/// @{
///\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 whether it is correct to call this method after
///%Suurballe for it is just a special case of Edmonds' and Karp's algorithm
///for finding minimum cost flows. In fact, this implementation just
///wraps the SspMinCostFlow 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::Value 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;
const Graph& G;
Node s;
Node t;
//Auxiliary variables
//This is the capacity map for the mincostflow problem
ConstMap const1map;
//This MinCostFlow instance will actually solve the problem
SspMinCostFlow min_cost_flow;
//Container to store found paths
std::vector > paths;
public :
/// \brief 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 _s Source node.
/// \param _t Target node.
Suurballe(Graph& _G, LengthMap& _length, Node _s, Node _t) :
G(_G), s(_s), t(_t), const1map(1),
min_cost_flow(_G, _length, const1map, _s, _t) { }
/// \brief 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 edge-disjoint paths found
/// from s to t.
///
/// \param k How many paths are we looking for?
///
int run(int k) {
int i = min_cost_flow.run(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 min_cost_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] = min_cost_flow.getFlow()[e];
paths.clear();
paths.resize(k);
for (int j=0; j* Path;
/// \brief Read the found paths.
///
/// This function gives back the \c j-th path in argument p.
/// Assumes that \c run() has been run and nothing has changed
/// since then.
///
/// \warning It is assumed that \c p is constructed to be a path
/// of graph \c G. If \c j is not less than the result of
/// previous \c run, then the result here will be an empty path
/// (\c j can be 0 as well).
///
/// \param j Which path you want to get from the found paths (in a
/// real application you would get the found paths iteratively).
Path path(int j) const {
return paths[j];
}
/// \brief Gives back the number of the paths.
///
/// Gives back the number of the constructed paths.
int pathNum() const {
return paths.size();
}
}; //class Suurballe
///@}
} //namespace lemon
#endif //LEMON_SUURBALLE_H
*