# HG changeset patch
# User alpar
# Date 1095846941 0
# Node ID f485b3008cf537b9a1287ba094a0e2e5cc05f88e
# Parent  c46cfb2651ec2b29dfd4861c63b8e4f8cfd6c1ce
Classes (and corresponting file names) renamed:
- MinLengthPaths -> Suurballe
- MinCostFlows -> MinCostFlow

diff -r c46cfb2651ec -r f485b3008cf5 src/hugo/Makefile.am
--- a/src/hugo/Makefile.am	Wed Sep 22 08:54:53 2004 +0000
+++ b/src/hugo/Makefile.am	Wed Sep 22 09:55:41 2004 +0000
@@ -18,8 +18,8 @@
 	map_registry.h                                                  \
 	map_bits.h							\
 	maps.h								\
-	min_cost_flows.h                                                \
-	min_length_paths.h                                              \
+	min_cost_flow.h                                                \
+	suurballe.h                                                     \
 	preflow.h                                                       \
 	path.h                                                          \
 	smart_graph.h							\
diff -r c46cfb2651ec -r f485b3008cf5 src/hugo/min_cost_flow.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hugo/min_cost_flow.h	Wed Sep 22 09:55:41 2004 +0000
@@ -0,0 +1,241 @@
+// -*- c++ -*-
+#ifndef HUGO_MINCOSTFLOWS_H
+#define HUGO_MINCOSTFLOWS_H
+
+///\ingroup flowalgs
+///\file
+///\brief An algorithm for finding a flow of value \c k (for small values of \c k) having minimal total cost 
+
+
+#include <hugo/dijkstra.h>
+#include <hugo/graph_wrapper.h>
+#include <hugo/maps.h>
+#include <vector>
+
+namespace hugo {
+
+/// \addtogroup flowalgs
+/// @{
+
+  ///\brief Implementation of an algorithm for finding a flow of value \c k 
+  ///(for small values of \c k) having minimal total cost between 2 nodes 
+  /// 
+  ///
+  /// The class \ref hugo::MinCostFlow "MinCostFlow" implements
+  /// an algorithm for finding a flow of value \c k 
+  /// having minimal total cost 
+  /// from a given source node to a given target node in an
+  /// edge-weighted directed graph. To this end, 
+  /// the edge-capacities and edge-weitghs have to be nonnegative. 
+  /// The edge-capacities should be integers, but the edge-weights can be 
+  /// integers, reals or of other comparable numeric type.
+  /// This algorithm is intended to use only for small values of \c k, 
+  /// since it is only polynomial in k, 
+  /// not in the length of k (which is log k). 
+  /// In order to find the minimum cost flow of value \c k it 
+  /// finds the minimum cost flow of value \c i for every 
+  /// \c i between 0 and \c k. 
+  ///
+  ///\param Graph The directed graph type the algorithm runs on.
+  ///\param LengthMap The type of the length map.
+  ///\param CapacityMap The capacity map type.
+  ///
+  ///\author Attila Bernath
+  template <typename Graph, typename LengthMap, typename CapacityMap>
+  class MinCostFlow {
+
+    typedef typename LengthMap::ValueType Length;
+
+    //Warning: this should be integer type
+    typedef typename CapacityMap::ValueType Capacity;
+    
+    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<int> EdgeIntMap;
+
+
+    typedef ResGraphWrapper<const Graph,int,CapacityMap,EdgeIntMap> ResGraphType;
+    typedef typename ResGraphType::Edge ResGraphEdge;
+
+    class ModLengthMap {   
+      typedef typename Graph::template NodeMap<Length> NodeMap;
+      const ResGraphType& G;
+      const LengthMap &ol;
+      const NodeMap &pot;
+    public :
+      typedef typename LengthMap::KeyType KeyType;
+      typedef typename LengthMap::ValueType ValueType;
+	
+      ValueType operator[](typename ResGraphType::Edge e) const {     
+	if (G.forward(e))
+	  return  ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);   
+	else
+	  return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);   
+      }     
+	
+      ModLengthMap(const ResGraphType& _G,
+		   const LengthMap &o,  const NodeMap &p) : 
+	G(_G), /*rev(_rev),*/ ol(o), pot(p){}; 
+    };//ModLengthMap
+
+
+  protected:
+    
+    //Input
+    const Graph& G;
+    const LengthMap& length;
+    const CapacityMap& capacity;
+
+
+    //auxiliary variables
+
+    //To store the flow
+    EdgeIntMap flow; 
+    //To store the potential (dual variables)
+    typedef typename Graph::template NodeMap<Length> PotentialMap;
+    PotentialMap potential;
+    
+
+    Length total_length;
+
+
+  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. 
+    ///\param _cap The capacity of the edges. 
+    MinCostFlow(Graph& _G, LengthMap& _length, CapacityMap& _cap) : G(_G), 
+      length(_length), capacity(_cap), flow(_G), potential(_G){ }
+
+    
+    ///Runs the algorithm.
+    
+    ///Runs the algorithm.
+    ///Returns k if there is a flow of value at least k edge-disjoint 
+    ///from s to t.
+    ///Otherwise it returns the maximum value of a flow from s to t.
+    ///
+    ///\param s The source node.
+    ///\param t The target node.
+    ///\param k The value of the flow we are looking for.
+    ///
+    ///\todo May be it does make sense to be able to start with a nonzero 
+    /// feasible primal-dual solution pair as well.
+    int run(Node s, Node t, int k) {
+
+      //Resetting variables from previous runs
+      total_length = 0;
+      
+      for (typename Graph::EdgeIt e(G); e!=INVALID; ++e) flow.set(e, 0);
+
+      //Initialize the potential to zero
+      for (typename Graph::NodeIt n(G); n!=INVALID; ++n) potential.set(n, 0);
+      
+      
+      //We need a residual graph
+      ResGraphType res_graph(G, capacity, flow);
+
+
+      ModLengthMap mod_length(res_graph, length, potential);
+
+      Dijkstra<ResGraphType, ModLengthMap> dijkstra(res_graph, mod_length);
+
+      int i;
+      for (i=0; i<k; ++i){
+	dijkstra.run(s);
+	if (!dijkstra.reached(t)){
+	  //There are no flow of value k from s to t
+	  break;
+	};
+	
+	//We have to change the potential
+        for(typename ResGraphType::NodeIt n(res_graph); n!=INVALID; ++n)
+	  potential[n] += dijkstra.distMap()[n];
+
+
+	//Augmenting on the sortest path
+	Node n=t;
+	ResGraphEdge e;
+	while (n!=s){
+	  e = dijkstra.pred(n);
+	  n = dijkstra.predNode(n);
+	  res_graph.augment(e,1);
+	  //Let's update the total length
+	  if (res_graph.forward(e))
+	    total_length += length[e];
+	  else 
+	    total_length -= length[e];	    
+	}
+
+	  
+      }
+      
+
+      return i;
+    }
+
+
+
+    /// Gives back the total weight of the found flow.
+
+    ///This function gives back the total weight of the found flow.
+    ///Assumes that \c run() has been run and nothing changed since then.
+    Length totalLength(){
+      return total_length;
+    }
+
+    ///Returns a const reference to the EdgeMap \c flow. 
+
+    ///Returns a const reference to the EdgeMap \c flow. 
+    ///\pre \ref run() must
+    ///be called before using this function.
+    const EdgeIntMap &getFlow() const { return flow;}
+
+    ///Returns a const reference to the NodeMap \c potential (the dual solution).
+
+    ///Returns a const reference to the NodeMap \c potential (the dual solution).
+    /// \pre \ref run() must be called before using this function.
+    const PotentialMap &getPotential() const { return potential;}
+
+    /// Checking the complementary slackness optimality criteria
+
+    ///This function checks, whether the given solution is optimal
+    ///If executed after the call of \c run() then it should return with true.
+    ///This function only checks optimality, doesn't bother with feasibility.
+    ///It is meant for testing purposes.
+    ///
+    bool checkComplementarySlackness(){
+      Length mod_pot;
+      Length fl_e;
+        for(typename Graph::EdgeIt e(G); e!=INVALID; ++e) {
+	//C^{\Pi}_{i,j}
+	mod_pot = length[e]-potential[G.head(e)]+potential[G.tail(e)];
+	fl_e = flow[e];
+	if (0<fl_e && fl_e<capacity[e]) {
+	  /// \todo better comparison is needed for real types, moreover, 
+	  /// this comparison here is superfluous.
+	  if (mod_pot != 0)
+	    return false;
+	} 
+	else {
+	  if (mod_pot > 0 && fl_e != 0)
+	    return false;
+	  if (mod_pot < 0 && fl_e != capacity[e])
+	    return false;
+	}
+      }
+      return true;
+    }
+    
+
+  }; //class MinCostFlow
+
+  ///@}
+
+} //namespace hugo
+
+#endif //HUGO_MINCOSTFLOWS_H
diff -r c46cfb2651ec -r f485b3008cf5 src/hugo/min_cost_flows.h
--- a/src/hugo/min_cost_flows.h	Wed Sep 22 08:54:53 2004 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-// -*- c++ -*-
-#ifndef HUGO_MINCOSTFLOWS_H
-#define HUGO_MINCOSTFLOWS_H
-
-///\ingroup flowalgs
-///\file
-///\brief An algorithm for finding a flow of value \c k (for small values of \c k) having minimal total cost 
-
-
-#include <hugo/dijkstra.h>
-#include <hugo/graph_wrapper.h>
-#include <hugo/maps.h>
-#include <vector>
-
-namespace hugo {
-
-/// \addtogroup flowalgs
-/// @{
-
-  ///\brief Implementation of an algorithm for finding a flow of value \c k 
-  ///(for small values of \c k) having minimal total cost between 2 nodes 
-  /// 
-  ///
-  /// The class \ref hugo::MinCostFlows "MinCostFlows" implements
-  /// an algorithm for finding a flow of value \c k 
-  /// having minimal total cost 
-  /// from a given source node to a given target node in an
-  /// edge-weighted directed graph. To this end, 
-  /// the edge-capacities and edge-weitghs have to be nonnegative. 
-  /// The edge-capacities should be integers, but the edge-weights can be 
-  /// integers, reals or of other comparable numeric type.
-  /// This algorithm is intended to use only for small values of \c k, 
-  /// since it is only polynomial in k, 
-  /// not in the length of k (which is log k). 
-  /// In order to find the minimum cost flow of value \c k it 
-  /// finds the minimum cost flow of value \c i for every 
-  /// \c i between 0 and \c k. 
-  ///
-  ///\param Graph The directed graph type the algorithm runs on.
-  ///\param LengthMap The type of the length map.
-  ///\param CapacityMap The capacity map type.
-  ///
-  ///\author Attila Bernath
-  template <typename Graph, typename LengthMap, typename CapacityMap>
-  class MinCostFlows {
-
-    typedef typename LengthMap::ValueType Length;
-
-    //Warning: this should be integer type
-    typedef typename CapacityMap::ValueType Capacity;
-    
-    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<int> EdgeIntMap;
-
-
-    typedef ResGraphWrapper<const Graph,int,CapacityMap,EdgeIntMap> ResGraphType;
-    typedef typename ResGraphType::Edge ResGraphEdge;
-
-    class ModLengthMap {   
-      typedef typename Graph::template NodeMap<Length> NodeMap;
-      const ResGraphType& G;
-      const LengthMap &ol;
-      const NodeMap &pot;
-    public :
-      typedef typename LengthMap::KeyType KeyType;
-      typedef typename LengthMap::ValueType ValueType;
-	
-      ValueType operator[](typename ResGraphType::Edge e) const {     
-	if (G.forward(e))
-	  return  ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);   
-	else
-	  return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);   
-      }     
-	
-      ModLengthMap(const ResGraphType& _G,
-		   const LengthMap &o,  const NodeMap &p) : 
-	G(_G), /*rev(_rev),*/ ol(o), pot(p){}; 
-    };//ModLengthMap
-
-
-  protected:
-    
-    //Input
-    const Graph& G;
-    const LengthMap& length;
-    const CapacityMap& capacity;
-
-
-    //auxiliary variables
-
-    //To store the flow
-    EdgeIntMap flow; 
-    //To store the potential (dual variables)
-    typedef typename Graph::template NodeMap<Length> PotentialMap;
-    PotentialMap potential;
-    
-
-    Length total_length;
-
-
-  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. 
-    ///\param _cap The capacity of the edges. 
-    MinCostFlows(Graph& _G, LengthMap& _length, CapacityMap& _cap) : G(_G), 
-      length(_length), capacity(_cap), flow(_G), potential(_G){ }
-
-    
-    ///Runs the algorithm.
-    
-    ///Runs the algorithm.
-    ///Returns k if there is a flow of value at least k edge-disjoint 
-    ///from s to t.
-    ///Otherwise it returns the maximum value of a flow from s to t.
-    ///
-    ///\param s The source node.
-    ///\param t The target node.
-    ///\param k The value of the flow we are looking for.
-    ///
-    ///\todo May be it does make sense to be able to start with a nonzero 
-    /// feasible primal-dual solution pair as well.
-    int run(Node s, Node t, int k) {
-
-      //Resetting variables from previous runs
-      total_length = 0;
-      
-      for (typename Graph::EdgeIt e(G); e!=INVALID; ++e) flow.set(e, 0);
-
-      //Initialize the potential to zero
-      for (typename Graph::NodeIt n(G); n!=INVALID; ++n) potential.set(n, 0);
-      
-      
-      //We need a residual graph
-      ResGraphType res_graph(G, capacity, flow);
-
-
-      ModLengthMap mod_length(res_graph, length, potential);
-
-      Dijkstra<ResGraphType, ModLengthMap> dijkstra(res_graph, mod_length);
-
-      int i;
-      for (i=0; i<k; ++i){
-	dijkstra.run(s);
-	if (!dijkstra.reached(t)){
-	  //There are no flow of value k from s to t
-	  break;
-	};
-	
-	//We have to change the potential
-        for(typename ResGraphType::NodeIt n(res_graph); n!=INVALID; ++n)
-	  potential[n] += dijkstra.distMap()[n];
-
-
-	//Augmenting on the sortest path
-	Node n=t;
-	ResGraphEdge e;
-	while (n!=s){
-	  e = dijkstra.pred(n);
-	  n = dijkstra.predNode(n);
-	  res_graph.augment(e,1);
-	  //Let's update the total length
-	  if (res_graph.forward(e))
-	    total_length += length[e];
-	  else 
-	    total_length -= length[e];	    
-	}
-
-	  
-      }
-      
-
-      return i;
-    }
-
-
-
-    /// Gives back the total weight of the found flow.
-
-    ///This function gives back the total weight of the found flow.
-    ///Assumes that \c run() has been run and nothing changed since then.
-    Length totalLength(){
-      return total_length;
-    }
-
-    ///Returns a const reference to the EdgeMap \c flow. 
-
-    ///Returns a const reference to the EdgeMap \c flow. 
-    ///\pre \ref run() must
-    ///be called before using this function.
-    const EdgeIntMap &getFlow() const { return flow;}
-
-    ///Returns a const reference to the NodeMap \c potential (the dual solution).
-
-    ///Returns a const reference to the NodeMap \c potential (the dual solution).
-    /// \pre \ref run() must be called before using this function.
-    const PotentialMap &getPotential() const { return potential;}
-
-    /// Checking the complementary slackness optimality criteria
-
-    ///This function checks, whether the given solution is optimal
-    ///If executed after the call of \c run() then it should return with true.
-    ///This function only checks optimality, doesn't bother with feasibility.
-    ///It is meant for testing purposes.
-    ///
-    bool checkComplementarySlackness(){
-      Length mod_pot;
-      Length fl_e;
-        for(typename Graph::EdgeIt e(G); e!=INVALID; ++e) {
-	//C^{\Pi}_{i,j}
-	mod_pot = length[e]-potential[G.head(e)]+potential[G.tail(e)];
-	fl_e = flow[e];
-	if (0<fl_e && fl_e<capacity[e]) {
-	  /// \todo better comparison is needed for real types, moreover, 
-	  /// this comparison here is superfluous.
-	  if (mod_pot != 0)
-	    return false;
-	} 
-	else {
-	  if (mod_pot > 0 && fl_e != 0)
-	    return false;
-	  if (mod_pot < 0 && fl_e != capacity[e])
-	    return false;
-	}
-      }
-      return true;
-    }
-    
-
-  }; //class MinCostFlows
-
-  ///@}
-
-} //namespace hugo
-
-#endif //HUGO_MINCOSTFLOWS_H
diff -r c46cfb2651ec -r f485b3008cf5 src/hugo/min_length_paths.h
--- a/src/hugo/min_length_paths.h	Wed Sep 22 08:54:53 2004 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-// -*- c++ -*-
-#ifndef HUGO_MINLENGTHPATHS_H
-#define HUGO_MINLENGTHPATHS_H
-
-///\ingroup flowalgs
-///\file
-///\brief An algorithm for finding k paths of minimal total length.
-
-
-#include <hugo/maps.h>
-#include <vector>
-#include <hugo/min_cost_flows.h>
-
-namespace hugo {
-
-/// \addtogroup flowalgs
-/// @{
-
-  ///\brief Implementation of an algorithm for finding k edge-disjoint paths between 2 nodes 
-  /// of minimal total length 
-  ///
-  /// The class \ref hugo::MinLengthPaths 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).
-  ///
-  ///\author Attila Bernath
-  template <typename Graph, typename LengthMap>
-  class MinLengthPaths{
-
-
-    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<int> EdgeIntMap;
-
-    typedef ConstMap<Edge,int> ConstMap;
-
-    //Input
-    const Graph& G;
-
-    //Auxiliary variables
-    //This is the capacity map for the mincostflow problem
-    ConstMap const1map;
-    //This MinCostFlows instance will actually solve the problem
-    MinCostFlows<Graph, LengthMap, ConstMap> mincost_flow;
-
-    //Container to store found paths
-    std::vector< std::vector<Edge> > 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. 
-    MinLengthPaths(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<i; ++j){
-	Node n=s;
-	OutEdgeIt e;
-
-	while (n!=t){
-
-
-	  G.first(e,n);
-	  
-	  while (!reversed[e]){
-	    ++e;
-	  }
-	  n = G.head(e);
-	  paths[j].push_back(e);
-	  //total_length += length[e];
-	  reversed[e] = 1-reversed[e];
-	}
-	
-      }
-      return i;
-    }
-
-    
-    ///Returns the total length of the paths
-    
-    ///This function gives back the total length of the found paths.
-    ///\pre \ref run() must
-    ///be called before using this function.
-    Length totalLength(){
-      return mincost_flow.totalLength();
-    }
-
-    ///Returns the found flow.
-
-    ///This function returns a const reference to the EdgeMap \c flow.
-    ///\pre \ref run() must
-    ///be called before using this function.
-    const EdgeIntMap &getFlow() const { return mincost_flow.flow;}
-
-    /// Returns the optimal dual solution
-    
-    ///This function returns a const reference to the NodeMap
-    ///\c potential (the dual solution).
-    /// \pre \ref run() must be called before using this function.
-    const EdgeIntMap &getPotential() const { return mincost_flow.potential;}
-
-    ///Checks whether the complementary slackness holds.
-
-    ///This function checks, whether the given solution is optimal.
-    ///It should return true after calling \ref run() 
-    ///Currently this function only checks optimality,
-    ///doesn't bother with feasibility
-    ///It is meant for testing purposes.
-    ///
-    bool checkComplementarySlackness(){
-      return mincost_flow.checkComplementarySlackness();
-    }
-
-    ///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 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 Path The type of the path structure to put the result to (must meet hugo path concept).
-    ///\param p The path to put the result to 
-    ///\param j Which path you want to get from the found paths (in a real application you would get the found paths iteratively)
-    template<typename Path>
-    void getPath(Path& p, size_t j){
-
-      p.clear();
-      if (j>paths.size()-1){
-	return;
-      }
-      typename Path::Builder B(p);
-      for(typename std::vector<Edge>::iterator i=paths[j].begin(); 
-	  i!=paths[j].end(); ++i ){
-	B.pushBack(*i);
-      }
-
-      B.commit();
-    }
-
-  }; //class MinLengthPaths
-
-  ///@}
-
-} //namespace hugo
-
-#endif //HUGO_MINLENGTHPATHS_H
diff -r c46cfb2651ec -r f485b3008cf5 src/hugo/suurballe.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hugo/suurballe.h	Wed Sep 22 09:55:41 2004 +0000
@@ -0,0 +1,200 @@
+// -*- c++ -*-
+#ifndef HUGO_MINLENGTHPATHS_H
+#define HUGO_MINLENGTHPATHS_H
+
+///\ingroup flowalgs
+///\file
+///\brief An algorithm for finding k paths of minimal total length.
+
+
+#include <hugo/maps.h>
+#include <vector>
+#include <hugo/min_cost_flow.h>
+
+namespace hugo {
+
+/// \addtogroup flowalgs
+/// @{
+
+  ///\brief Implementation of an algorithm for finding k edge-disjoint paths between 2 nodes 
+  /// of minimal total length 
+  ///
+  /// The class \ref hugo::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 <typename Graph, typename LengthMap>
+  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<int> EdgeIntMap;
+
+    typedef ConstMap<Edge,int> 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<Graph, LengthMap, ConstMap> mincost_flow;
+
+    //Container to store found paths
+    std::vector< std::vector<Edge> > 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<i; ++j){
+	Node n=s;
+	OutEdgeIt e;
+
+	while (n!=t){
+
+
+	  G.first(e,n);
+	  
+	  while (!reversed[e]){
+	    ++e;
+	  }
+	  n = G.head(e);
+	  paths[j].push_back(e);
+	  //total_length += length[e];
+	  reversed[e] = 1-reversed[e];
+	}
+	
+      }
+      return i;
+    }
+
+    
+    ///Returns the total length of the paths
+    
+    ///This function gives back the total length of the found paths.
+    ///\pre \ref run() must
+    ///be called before using this function.
+    Length totalLength(){
+      return mincost_flow.totalLength();
+    }
+
+    ///Returns the found flow.
+
+    ///This function returns a const reference to the EdgeMap \c flow.
+    ///\pre \ref run() must
+    ///be called before using this function.
+    const EdgeIntMap &getFlow() const { return mincost_flow.flow;}
+
+    /// Returns the optimal dual solution
+    
+    ///This function returns a const reference to the NodeMap
+    ///\c potential (the dual solution).
+    /// \pre \ref run() must be called before using this function.
+    const EdgeIntMap &getPotential() const { return mincost_flow.potential;}
+
+    ///Checks whether the complementary slackness holds.
+
+    ///This function checks, whether the given solution is optimal.
+    ///It should return true after calling \ref run() 
+    ///Currently this function only checks optimality,
+    ///doesn't bother with feasibility
+    ///It is meant for testing purposes.
+    ///
+    bool checkComplementarySlackness(){
+      return mincost_flow.checkComplementarySlackness();
+    }
+
+    ///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 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 Path The type of the path structure to put the result to (must meet hugo path concept).
+    ///\param p The path to put the result to 
+    ///\param j Which path you want to get from the found paths (in a real application you would get the found paths iteratively)
+    template<typename Path>
+    void getPath(Path& p, size_t j){
+
+      p.clear();
+      if (j>paths.size()-1){
+	return;
+      }
+      typename Path::Builder B(p);
+      for(typename std::vector<Edge>::iterator i=paths[j].begin(); 
+	  i!=paths[j].end(); ++i ){
+	B.pushBack(*i);
+      }
+
+      B.commit();
+    }
+
+  }; //class Suurballe
+
+  ///@}
+
+} //namespace hugo
+
+#endif //HUGO_MINLENGTHPATHS_H
diff -r c46cfb2651ec -r f485b3008cf5 src/test/Makefile.am
--- a/src/test/Makefile.am	Wed Sep 22 08:54:53 2004 +0000
+++ b/src/test/Makefile.am	Wed Sep 22 09:55:41 2004 +0000
@@ -11,8 +11,8 @@
 	graph_test \
 	graph_wrapper_test \
 	kruskal_test \
-	min_cost_flows_test \
-	min_length_paths_test \
+	min_cost_flow_test \
+	suurballe_test \
 	path_test \
 	preflow_test \
 	test_tools_fail \
@@ -30,8 +30,8 @@
 graph_test_SOURCES = graph_test.cc
 graph_wrapper_test_SOURCES = graph_wrapper_test.cc
 kruskal_test_SOURCES = kruskal_test.cc
-min_cost_flows_test_SOURCES = min_cost_flows_test.cc
-min_length_paths_test_SOURCES = min_length_paths_test.cc
+min_cost_flow_test_SOURCES = min_cost_flow_test.cc
+suurballe_test_SOURCES = suurballe_test.cc
 path_test_SOURCES = path_test.cc
 preflow_test_SOURCES = preflow_test.cc
 time_measure_test_SOURCES = time_measure_test.cc
diff -r c46cfb2651ec -r f485b3008cf5 src/test/min_cost_flow_test.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/min_cost_flow_test.cc	Wed Sep 22 09:55:41 2004 +0000
@@ -0,0 +1,107 @@
+#include <iostream>
+#include "test_tools.h"
+#include <hugo/list_graph.h>
+#include <hugo/min_cost_flow.h>
+//#include <path.h>
+//#include <maps.h>
+
+using namespace std;
+using namespace hugo;
+
+
+
+bool passed = true;
+/*
+void check(bool rc, char *msg="") {
+  passed = passed && rc;
+  if(!rc) {
+    std::cerr << "Test failed! ("<< msg << ")" << std::endl; \
+ 
+
+  }
+}
+*/
+
+
+int main()
+{
+
+  typedef ListGraph::Node Node;
+  typedef ListGraph::Edge Edge;
+
+  ListGraph graph;
+
+  //Ahuja könyv példája
+
+  Node s=graph.addNode();
+  Node v1=graph.addNode();  
+  Node v2=graph.addNode();
+  Node v3=graph.addNode();
+  Node v4=graph.addNode();
+  Node v5=graph.addNode();
+  Node t=graph.addNode();
+
+  Edge s_v1=graph.addEdge(s, v1);
+  Edge v1_v2=graph.addEdge(v1, v2);
+  Edge s_v3=graph.addEdge(s, v3);
+  Edge v2_v4=graph.addEdge(v2, v4);
+  Edge v2_v5=graph.addEdge(v2, v5);
+  Edge v3_v5=graph.addEdge(v3, v5);
+  Edge v4_t=graph.addEdge(v4, t);
+  Edge v5_t=graph.addEdge(v5, t);
+  
+
+  ListGraph::EdgeMap<int> length(graph);
+
+  length.set(s_v1, 6);
+  length.set(v1_v2, 4);
+  length.set(s_v3, 10);
+  length.set(v2_v4, 5);
+  length.set(v2_v5, 1);
+  length.set(v3_v5, 4);
+  length.set(v4_t, 8);
+  length.set(v5_t, 8);
+
+  ListGraph::EdgeMap<int> capacity(graph);
+
+  capacity.set(s_v1, 2);
+  capacity.set(v1_v2, 2);
+  capacity.set(s_v3, 1);
+  capacity.set(v2_v4, 1);
+  capacity.set(v2_v5, 1);
+  capacity.set(v3_v5, 1);
+  capacity.set(v4_t, 1);
+  capacity.set(v5_t, 2);
+
+  //  ConstMap<Edge, int> const1map(1);
+  std::cout << "Mincostflows algorithm test..." << std::endl;
+
+  MinCostFlow< ListGraph, ListGraph::EdgeMap<int>, ListGraph::EdgeMap<int> >
+    surb_test(graph, length, capacity);
+
+  int k=1;
+
+  check(  surb_test.run(s,t,k) == 1 && surb_test.totalLength() == 19,"One path, total length should be 19");
+
+  check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
+  
+  k=2;
+  
+  check(  surb_test.run(s,t,k) == 2 && surb_test.totalLength() == 41,"Two paths, total length should be 41");
+
+  check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
+  
+  
+  k=4;
+
+  check(  surb_test.run(s,t,k) == 3 && surb_test.totalLength() == 64,"Three paths, total length should be 64");
+
+  check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
+
+
+  cout << (passed ? "All tests passed." : "Some of the tests failed!!!")
+       << endl;
+
+  return passed ? 0 : 1;
+
+}
diff -r c46cfb2651ec -r f485b3008cf5 src/test/min_cost_flows_test.cc
--- a/src/test/min_cost_flows_test.cc	Wed Sep 22 08:54:53 2004 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-#include <iostream>
-#include "test_tools.h"
-#include <hugo/list_graph.h>
-#include <hugo/min_cost_flows.h>
-//#include <path.h>
-//#include <maps.h>
-
-using namespace std;
-using namespace hugo;
-
-
-
-bool passed = true;
-/*
-void check(bool rc, char *msg="") {
-  passed = passed && rc;
-  if(!rc) {
-    std::cerr << "Test failed! ("<< msg << ")" << std::endl; \
- 
-
-  }
-}
-*/
-
-
-int main()
-{
-
-  typedef ListGraph::Node Node;
-  typedef ListGraph::Edge Edge;
-
-  ListGraph graph;
-
-  //Ahuja könyv példája
-
-  Node s=graph.addNode();
-  Node v1=graph.addNode();  
-  Node v2=graph.addNode();
-  Node v3=graph.addNode();
-  Node v4=graph.addNode();
-  Node v5=graph.addNode();
-  Node t=graph.addNode();
-
-  Edge s_v1=graph.addEdge(s, v1);
-  Edge v1_v2=graph.addEdge(v1, v2);
-  Edge s_v3=graph.addEdge(s, v3);
-  Edge v2_v4=graph.addEdge(v2, v4);
-  Edge v2_v5=graph.addEdge(v2, v5);
-  Edge v3_v5=graph.addEdge(v3, v5);
-  Edge v4_t=graph.addEdge(v4, t);
-  Edge v5_t=graph.addEdge(v5, t);
-  
-
-  ListGraph::EdgeMap<int> length(graph);
-
-  length.set(s_v1, 6);
-  length.set(v1_v2, 4);
-  length.set(s_v3, 10);
-  length.set(v2_v4, 5);
-  length.set(v2_v5, 1);
-  length.set(v3_v5, 4);
-  length.set(v4_t, 8);
-  length.set(v5_t, 8);
-
-  ListGraph::EdgeMap<int> capacity(graph);
-
-  capacity.set(s_v1, 2);
-  capacity.set(v1_v2, 2);
-  capacity.set(s_v3, 1);
-  capacity.set(v2_v4, 1);
-  capacity.set(v2_v5, 1);
-  capacity.set(v3_v5, 1);
-  capacity.set(v4_t, 1);
-  capacity.set(v5_t, 2);
-
-  //  ConstMap<Edge, int> const1map(1);
-  std::cout << "Mincostflows algorithm test..." << std::endl;
-
-  MinCostFlows< ListGraph, ListGraph::EdgeMap<int>, ListGraph::EdgeMap<int> >
-    surb_test(graph, length, capacity);
-
-  int k=1;
-
-  check(  surb_test.run(s,t,k) == 1 && surb_test.totalLength() == 19,"One path, total length should be 19");
-
-  check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
-  
-  k=2;
-  
-  check(  surb_test.run(s,t,k) == 2 && surb_test.totalLength() == 41,"Two paths, total length should be 41");
-
-  check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
-  
-  
-  k=4;
-
-  check(  surb_test.run(s,t,k) == 3 && surb_test.totalLength() == 64,"Three paths, total length should be 64");
-
-  check(surb_test.checkComplementarySlackness(), "Is the primal-dual solution pair really optimal?");
-
-
-  cout << (passed ? "All tests passed." : "Some of the tests failed!!!")
-       << endl;
-
-  return passed ? 0 : 1;
-
-}
diff -r c46cfb2651ec -r f485b3008cf5 src/test/min_length_paths_test.cc
--- a/src/test/min_length_paths_test.cc	Wed Sep 22 08:54:53 2004 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-#include <iostream>
-#include <hugo/list_graph.h>
-#include <hugo/min_length_paths.h>
-//#include <path.h>
-#include "test_tools.h"
-
-using namespace std;
-using namespace hugo;
-
-
-
-bool passed = true;
-
-
-int main()
-{
-
-  typedef ListGraph::Node Node;
-  typedef ListGraph::Edge Edge;
-
-  ListGraph graph;
-
-  //Ahuja könyv példája
-
-  Node s=graph.addNode();
-  Node v1=graph.addNode();  
-  Node v2=graph.addNode();
-  Node v3=graph.addNode();
-  Node v4=graph.addNode();
-  Node v5=graph.addNode();
-  Node t=graph.addNode();
-
-  Edge s_v1=graph.addEdge(s, v1);
-  Edge v1_v2=graph.addEdge(v1, v2);
-  Edge s_v3=graph.addEdge(s, v3);
-  Edge v2_v4=graph.addEdge(v2, v4);
-  Edge v2_v5=graph.addEdge(v2, v5);
-  Edge v3_v5=graph.addEdge(v3, v5);
-  Edge v4_t=graph.addEdge(v4, t);
-  Edge v5_t=graph.addEdge(v5, t);
-  
-
-  ListGraph::EdgeMap<int> length(graph);
-
-  length.set(s_v1, 6);
-  length.set(v1_v2, 4);
-  length.set(s_v3, 10);
-  length.set(v2_v4, 5);
-  length.set(v2_v5, 1);
-  length.set(v3_v5, 5);
-  length.set(v4_t, 8);
-  length.set(v5_t, 8);
-
-  std::cout << "Minlengthpaths algorithm test..." << std::endl;
-
-  
-  int k=3;
-  MinLengthPaths< ListGraph, ListGraph::EdgeMap<int> >
-    surb_test(graph, length);
-
-  check(  surb_test.run(s,t,k) == 2 && surb_test.totalLength() == 46,
-	  "Two paths, total length should be 46");
-
-  check(  surb_test.checkComplementarySlackness(),
-	  "Complementary slackness conditions are not met.");
-
-  //  typedef DirPath<ListGraph> DPath;
-  //  DPath P(graph);
-
-  /*
-  surb_test.getPath(P,0);
-  check(P.length() == 4, "First path should contain 4 edges.");  
-  cout<<P.length()<<endl;
-  surb_test.getPath(P,1);
-  check(P.length() == 3, "Second path: 3 edges.");
-  cout<<P.length()<<endl;
-  */  
-
-  k=1;
-  check(  surb_test.run(s,t,k) == 1 && surb_test.totalLength() == 19,
-	  "One path, total length should be 19");
-
-  check(  surb_test.checkComplementarySlackness(),
-	  "Complementary slackness conditions are not met.");
- 
-  //  surb_test.getPath(P,0);
-  //  check(P.length() == 4, "First path should contain 4 edges.");  
-
-  cout << (passed ? "All tests passed." : "Some of the tests failed!!!")
-       << endl;
-
-  return passed ? 0 : 1;
-
-}
diff -r c46cfb2651ec -r f485b3008cf5 src/test/suurballe_test.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/suurballe_test.cc	Wed Sep 22 09:55:41 2004 +0000
@@ -0,0 +1,94 @@
+#include <iostream>
+#include <hugo/list_graph.h>
+#include <hugo/suurballe.h>
+//#include <path.h>
+#include "test_tools.h"
+
+using namespace std;
+using namespace hugo;
+
+
+
+bool passed = true;
+
+
+int main()
+{
+
+  typedef ListGraph::Node Node;
+  typedef ListGraph::Edge Edge;
+
+  ListGraph graph;
+
+  //Ahuja könyv példája
+
+  Node s=graph.addNode();
+  Node v1=graph.addNode();  
+  Node v2=graph.addNode();
+  Node v3=graph.addNode();
+  Node v4=graph.addNode();
+  Node v5=graph.addNode();
+  Node t=graph.addNode();
+
+  Edge s_v1=graph.addEdge(s, v1);
+  Edge v1_v2=graph.addEdge(v1, v2);
+  Edge s_v3=graph.addEdge(s, v3);
+  Edge v2_v4=graph.addEdge(v2, v4);
+  Edge v2_v5=graph.addEdge(v2, v5);
+  Edge v3_v5=graph.addEdge(v3, v5);
+  Edge v4_t=graph.addEdge(v4, t);
+  Edge v5_t=graph.addEdge(v5, t);
+  
+
+  ListGraph::EdgeMap<int> length(graph);
+
+  length.set(s_v1, 6);
+  length.set(v1_v2, 4);
+  length.set(s_v3, 10);
+  length.set(v2_v4, 5);
+  length.set(v2_v5, 1);
+  length.set(v3_v5, 5);
+  length.set(v4_t, 8);
+  length.set(v5_t, 8);
+
+  std::cout << "Minlengthpaths algorithm test..." << std::endl;
+
+  
+  int k=3;
+  Suurballe< ListGraph, ListGraph::EdgeMap<int> >
+    surb_test(graph, length);
+
+  check(  surb_test.run(s,t,k) == 2 && surb_test.totalLength() == 46,
+	  "Two paths, total length should be 46");
+
+  check(  surb_test.checkComplementarySlackness(),
+	  "Complementary slackness conditions are not met.");
+
+  //  typedef DirPath<ListGraph> DPath;
+  //  DPath P(graph);
+
+  /*
+  surb_test.getPath(P,0);
+  check(P.length() == 4, "First path should contain 4 edges.");  
+  cout<<P.length()<<endl;
+  surb_test.getPath(P,1);
+  check(P.length() == 3, "Second path: 3 edges.");
+  cout<<P.length()<<endl;
+  */  
+
+  k=1;
+  check(  surb_test.run(s,t,k) == 1 && surb_test.totalLength() == 19,
+	  "One path, total length should be 19");
+
+  check(  surb_test.checkComplementarySlackness(),
+	  "Complementary slackness conditions are not met.");
+ 
+  //  surb_test.getPath(P,0);
+  //  check(P.length() == 4, "First path should contain 4 edges.");  
+
+  cout << (passed ? "All tests passed." : "Some of the tests failed!!!")
+       << endl;
+
+  return passed ? 0 : 1;
+
+}