src/lemon/suurballe.h
changeset 1435 8e85e6bbefdf
parent 1434 d8475431bbbb
child 1436 e0beb94d08bf
     1.1 --- a/src/lemon/suurballe.h	Sat May 21 21:04:57 2005 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,209 +0,0 @@
     1.4 -/* -*- C++ -*-
     1.5 - * src/lemon/suurballe.h - Part of LEMON, a generic C++ optimization library
     1.6 - *
     1.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     1.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
     1.9 - *
    1.10 - * Permission to use, modify and distribute this software is granted
    1.11 - * provided that this copyright notice appears in all copies. For
    1.12 - * precise terms see the accompanying LICENSE file.
    1.13 - *
    1.14 - * This software is provided "AS IS" with no warranty of any kind,
    1.15 - * express or implied, and with no claim as to its suitability for any
    1.16 - * purpose.
    1.17 - *
    1.18 - */
    1.19 -
    1.20 -#ifndef LEMON_SUURBALLE_H
    1.21 -#define LEMON_SUURBALLE_H
    1.22 -
    1.23 -///\ingroup flowalgs
    1.24 -///\file
    1.25 -///\brief An algorithm for finding k paths of minimal total length.
    1.26 -
    1.27 -
    1.28 -#include <lemon/maps.h>
    1.29 -#include <vector>
    1.30 -#include <lemon/min_cost_flow.h>
    1.31 -
    1.32 -namespace lemon {
    1.33 -
    1.34 -/// \addtogroup flowalgs
    1.35 -/// @{
    1.36 -
    1.37 -  ///\brief Implementation of an algorithm for finding k edge-disjoint paths between 2 nodes 
    1.38 -  /// of minimal total length 
    1.39 -  ///
    1.40 -  /// The class \ref lemon::Suurballe implements
    1.41 -  /// an algorithm for finding k edge-disjoint paths
    1.42 -  /// from a given source node to a given target node in an
    1.43 -  /// edge-weighted directed graph having minimal total weight (length).
    1.44 -  ///
    1.45 -  ///\warning Length values should be nonnegative.
    1.46 -  /// 
    1.47 -  ///\param Graph The directed graph type the algorithm runs on.
    1.48 -  ///\param LengthMap The type of the length map (values should be nonnegative).
    1.49 -  ///
    1.50 -  ///\note It it questionable whether it is correct to call this method after
    1.51 -  ///%Suurballe for it is just a special case of Edmonds' and Karp's algorithm
    1.52 -  ///for finding minimum cost flows. In fact, this implementation just
    1.53 -  ///wraps the MinCostFlow algorithms. The paper of both %Suurballe and
    1.54 -  ///Edmonds-Karp published in 1972, therefore it is possibly right to
    1.55 -  ///state that they are
    1.56 -  ///independent results. Most frequently this special case is referred as
    1.57 -  ///%Suurballe method in the literature, especially in communication
    1.58 -  ///network context.
    1.59 -  ///\author Attila Bernath
    1.60 -  template <typename Graph, typename LengthMap>
    1.61 -  class Suurballe{
    1.62 -
    1.63 -
    1.64 -    typedef typename LengthMap::Value Length;
    1.65 -    
    1.66 -    typedef typename Graph::Node Node;
    1.67 -    typedef typename Graph::NodeIt NodeIt;
    1.68 -    typedef typename Graph::Edge Edge;
    1.69 -    typedef typename Graph::OutEdgeIt OutEdgeIt;
    1.70 -    typedef typename Graph::template EdgeMap<int> EdgeIntMap;
    1.71 -
    1.72 -    typedef ConstMap<Edge,int> ConstMap;
    1.73 -
    1.74 -    const Graph& G;
    1.75 -
    1.76 -    Node s;
    1.77 -    Node t;
    1.78 -
    1.79 -    //Auxiliary variables
    1.80 -    //This is the capacity map for the mincostflow problem
    1.81 -    ConstMap const1map;
    1.82 -    //This MinCostFlow instance will actually solve the problem
    1.83 -    MinCostFlow<Graph, LengthMap, ConstMap> min_cost_flow;
    1.84 -
    1.85 -    //Container to store found paths
    1.86 -    std::vector< std::vector<Edge> > paths;
    1.87 -
    1.88 -  public :
    1.89 -
    1.90 -
    1.91 -    /*! \brief The constructor of the class.
    1.92 -    
    1.93 -    \param _G The directed graph the algorithm runs on. 
    1.94 -    \param _length The length (weight or cost) of the edges. 
    1.95 -    \param _s Source node.
    1.96 -    \param _t Target node.
    1.97 -    */
    1.98 -    Suurballe(Graph& _G, LengthMap& _length, Node _s, Node _t) : 
    1.99 -      G(_G), s(_s), t(_t), const1map(1), 
   1.100 -      min_cost_flow(_G, _length, const1map, _s, _t) { }
   1.101 -
   1.102 -    ///Runs the algorithm.
   1.103 -
   1.104 -    ///Runs the algorithm.
   1.105 -    ///Returns k if there are at least k edge-disjoint paths from s to t.
   1.106 -    ///Otherwise it returns the number of edge-disjoint paths found 
   1.107 -    ///from s to t.
   1.108 -    ///
   1.109 -    ///\param k How many paths are we looking for?
   1.110 -    ///
   1.111 -    int run(int k) {
   1.112 -      int i = min_cost_flow.run(k);
   1.113 -
   1.114 -      //Let's find the paths
   1.115 -      //We put the paths into stl vectors (as an inner representation). 
   1.116 -      //In the meantime we lose the information stored in 'reversed'.
   1.117 -      //We suppose the lengths to be positive now.
   1.118 -
   1.119 -      //We don't want to change the flow of min_cost_flow, so we make a copy
   1.120 -      //The name here suggests that the flow has only 0/1 values.
   1.121 -      EdgeIntMap reversed(G); 
   1.122 -
   1.123 -      for(typename Graph::EdgeIt e(G); e!=INVALID; ++e) 
   1.124 -	reversed[e] = min_cost_flow.getFlow()[e];
   1.125 -      
   1.126 -      paths.clear();
   1.127 -      //total_length=0;
   1.128 -      paths.resize(k);
   1.129 -      for (int j=0; j<i; ++j){
   1.130 -	Node n=s;
   1.131 -
   1.132 -	while (n!=t){
   1.133 -
   1.134 -	  OutEdgeIt e(G, n);
   1.135 -	  
   1.136 -	  while (!reversed[e]){
   1.137 -	    ++e;
   1.138 -	  }
   1.139 -	  n = G.target(e);
   1.140 -	  paths[j].push_back(e);
   1.141 -	  //total_length += length[e];
   1.142 -	  reversed[e] = 1-reversed[e];
   1.143 -	}
   1.144 -	
   1.145 -      }
   1.146 -      return i;
   1.147 -    }
   1.148 -
   1.149 -    
   1.150 -    ///Returns the total length of the paths.
   1.151 -    
   1.152 -    ///This function gives back the total length of the found paths.
   1.153 -    Length totalLength(){
   1.154 -      return min_cost_flow.totalLength();
   1.155 -    }
   1.156 -
   1.157 -    ///Returns the found flow.
   1.158 -
   1.159 -    ///This function returns a const reference to the EdgeMap \c flow.
   1.160 -    const EdgeIntMap &getFlow() const { return min_cost_flow.flow;}
   1.161 -
   1.162 -    /// Returns the optimal dual solution
   1.163 -    
   1.164 -    ///This function returns a const reference to the NodeMap
   1.165 -    ///\c potential (the dual solution).
   1.166 -    const EdgeIntMap &getPotential() const { return min_cost_flow.potential;}
   1.167 -
   1.168 -    ///Checks whether the complementary slackness holds.
   1.169 -
   1.170 -    ///This function checks, whether the given solution is optimal.
   1.171 -    ///Currently this function only checks optimality,
   1.172 -    ///doesn't bother with feasibility
   1.173 -    ///It is meant for testing purposes.
   1.174 -    bool checkComplementarySlackness(){
   1.175 -      return min_cost_flow.checkComplementarySlackness();
   1.176 -    }
   1.177 -
   1.178 -    ///Read the found paths.
   1.179 -    
   1.180 -    ///This function gives back the \c j-th path in argument p.
   1.181 -    ///Assumes that \c run() has been run and nothing changed since then.
   1.182 -    /// \warning It is assumed that \c p is constructed to
   1.183 -    ///be a path of graph \c G.
   1.184 -    ///If \c j is not less than the result of previous \c run,
   1.185 -    ///then the result here will be an empty path (\c j can be 0 as well).
   1.186 -    ///
   1.187 -    ///\param Path The type of the path structure to put the result to (must meet lemon path concept).
   1.188 -    ///\param p The path to put the result to 
   1.189 -    ///\param j Which path you want to get from the found paths (in a real application you would get the found paths iteratively)
   1.190 -    template<typename Path>
   1.191 -    void getPath(Path& p, size_t j){
   1.192 -
   1.193 -      p.clear();
   1.194 -      if (j>paths.size()-1){
   1.195 -	return;
   1.196 -      }
   1.197 -      typename Path::Builder B(p);
   1.198 -      for(typename std::vector<Edge>::iterator i=paths[j].begin(); 
   1.199 -	  i!=paths[j].end(); ++i ){
   1.200 -	B.pushBack(*i);
   1.201 -      }
   1.202 -
   1.203 -      B.commit();
   1.204 -    }
   1.205 -
   1.206 -  }; //class Suurballe
   1.207 -
   1.208 -  ///@}
   1.209 -
   1.210 -} //namespace lemon
   1.211 -
   1.212 -#endif //LEMON_SUURBALLE_H