/* -*- C++ -*-
* lemon/suurballe.h - Part of LEMON, a generic C++ optimization library
*
* Copyright (C) 2005 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 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 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 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::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
MinCostFlow min_cost_flow;
//Container to store found paths
std::vector< 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) { }
///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*
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
*