lemon/dfs.h
changeset 281 e9b4fbe163f5
parent 280 e7f8647ce760
parent 278 931190050520
child 287 bb40b6db0a58
     1.1 --- a/lemon/dfs.h	Mon Jul 14 15:23:11 2008 +0100
     1.2 +++ b/lemon/dfs.h	Fri Sep 26 09:52:28 2008 +0200
     1.3 @@ -29,6 +29,7 @@
     1.4  #include <lemon/error.h>
     1.5  #include <lemon/assert.h>
     1.6  #include <lemon/maps.h>
     1.7 +#include <lemon/path.h>
     1.8  
     1.9  namespace lemon {
    1.10  
    1.11 @@ -114,7 +115,7 @@
    1.12    ///\ingroup search
    1.13    ///This class provides an efficient implementation of the %DFS algorithm.
    1.14    ///
    1.15 -  ///There is also a \ref dfs() "function type interface" for the DFS
    1.16 +  ///There is also a \ref dfs() "function-type interface" for the DFS
    1.17    ///algorithm, which is convenient in the simplier cases and it can be
    1.18    ///used easier.
    1.19    ///
    1.20 @@ -772,26 +773,22 @@
    1.21      ///The type of the map that stores the predecessor
    1.22      ///arcs of the %DFS paths.
    1.23      ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
    1.24 -    ///
    1.25 -    typedef NullMap<typename Digraph::Node,typename Digraph::Arc> PredMap;
    1.26 +    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
    1.27      ///Instantiates a \ref PredMap.
    1.28  
    1.29      ///This function instantiates a \ref PredMap.
    1.30      ///\param g is the digraph, to which we would like to define the
    1.31      ///\ref PredMap.
    1.32 -#ifdef DOXYGEN
    1.33      static PredMap *createPredMap(const Digraph &g)
    1.34 -#else
    1.35 -    static PredMap *createPredMap(const Digraph &)
    1.36 -#endif
    1.37      {
    1.38 -      return new PredMap();
    1.39 +      return new PredMap(g);
    1.40      }
    1.41  
    1.42      ///The type of the map that indicates which nodes are processed.
    1.43  
    1.44      ///The type of the map that indicates which nodes are processed.
    1.45      ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
    1.46 +    ///By default it is a NullMap.
    1.47      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
    1.48      ///Instantiates a \ref ProcessedMap.
    1.49  
    1.50 @@ -826,21 +823,22 @@
    1.51  
    1.52      ///The type of the map that stores the distances of the nodes.
    1.53      ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
    1.54 -    ///
    1.55 -    typedef NullMap<typename Digraph::Node,int> DistMap;
    1.56 +    typedef typename Digraph::template NodeMap<int> DistMap;
    1.57      ///Instantiates a \ref DistMap.
    1.58  
    1.59      ///This function instantiates a \ref DistMap.
    1.60      ///\param g is the digraph, to which we would like to define
    1.61      ///the \ref DistMap
    1.62 -#ifdef DOXYGEN
    1.63      static DistMap *createDistMap(const Digraph &g)
    1.64 -#else
    1.65 -    static DistMap *createDistMap(const Digraph &)
    1.66 -#endif
    1.67      {
    1.68 -      return new DistMap();
    1.69 +      return new DistMap(g);
    1.70      }
    1.71 +
    1.72 +    ///The type of the DFS paths.
    1.73 +
    1.74 +    ///The type of the DFS paths.
    1.75 +    ///It must meet the \ref concepts::Path "Path" concept.
    1.76 +    typedef lemon::Path<Digraph> Path;
    1.77    };
    1.78  
    1.79    /// Default traits class used by \ref DfsWizard
    1.80 @@ -870,51 +868,39 @@
    1.81      void *_pred;
    1.82      //Pointer to the map of distances.
    1.83      void *_dist;
    1.84 -    //Pointer to the source node.
    1.85 -    Node _source;
    1.86 +    //Pointer to the DFS path to the target node.
    1.87 +    void *_path;
    1.88 +    //Pointer to the distance of the target node.
    1.89 +    int *_di;
    1.90  
    1.91      public:
    1.92      /// Constructor.
    1.93  
    1.94      /// This constructor does not require parameters, therefore it initiates
    1.95 -    /// all of the attributes to default values (0, INVALID).
    1.96 +    /// all of the attributes to \c 0.
    1.97      DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
    1.98 -                      _dist(0), _source(INVALID) {}
    1.99 +                      _dist(0), _path(0), _di(0) {}
   1.100  
   1.101      /// Constructor.
   1.102  
   1.103 -    /// This constructor requires some parameters,
   1.104 -    /// listed in the parameters list.
   1.105 -    /// Others are initiated to 0.
   1.106 +    /// This constructor requires one parameter,
   1.107 +    /// others are initiated to \c 0.
   1.108      /// \param g The digraph the algorithm runs on.
   1.109 -    /// \param s The source node.
   1.110 -    DfsWizardBase(const GR &g, Node s=INVALID) :
   1.111 +    DfsWizardBase(const GR &g) :
   1.112        _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
   1.113 -      _reached(0), _processed(0), _pred(0), _dist(0), _source(s) {}
   1.114 +      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
   1.115  
   1.116    };
   1.117  
   1.118 -  /// Auxiliary class for the function type interface of DFS algorithm.
   1.119 +  /// Auxiliary class for the function-type interface of DFS algorithm.
   1.120  
   1.121 -  /// This auxiliary class is created to implement the function type
   1.122 -  /// interface of \ref Dfs algorithm. It uses the functions and features
   1.123 -  /// of the plain \ref Dfs, but it is much simpler to use it.
   1.124 -  /// It should only be used through the \ref dfs() function, which makes
   1.125 -  /// it easier to use the algorithm.
   1.126 +  /// This auxiliary class is created to implement the
   1.127 +  /// \ref dfs() "function-type interface" of \ref Dfs algorithm.
   1.128 +  /// It does not have own \ref run() method, it uses the functions
   1.129 +  /// and features of the plain \ref Dfs.
   1.130    ///
   1.131 -  /// Simplicity means that the way to change the types defined
   1.132 -  /// in the traits class is based on functions that returns the new class
   1.133 -  /// and not on templatable built-in classes.
   1.134 -  /// When using the plain \ref Dfs
   1.135 -  /// the new class with the modified type comes from
   1.136 -  /// the original class by using the ::
   1.137 -  /// operator. In the case of \ref DfsWizard only
   1.138 -  /// a function have to be called, and it will
   1.139 -  /// return the needed class.
   1.140 -  ///
   1.141 -  /// It does not have own \ref run() method. When its \ref run() method
   1.142 -  /// is called, it initiates a plain \ref Dfs object, and calls the
   1.143 -  /// \ref Dfs::run() method of it.
   1.144 +  /// This class should only be used through the \ref dfs() function,
   1.145 +  /// which makes it easier to use the algorithm.
   1.146    template<class TR>
   1.147    class DfsWizard : public TR
   1.148    {
   1.149 @@ -929,7 +915,7 @@
   1.150      typedef typename Digraph::OutArcIt OutArcIt;
   1.151  
   1.152      ///\brief The type of the map that stores the predecessor
   1.153 -    ///arcs of the shortest paths.
   1.154 +    ///arcs of the DFS paths.
   1.155      typedef typename TR::PredMap PredMap;
   1.156      ///\brief The type of the map that stores the distances of the nodes.
   1.157      typedef typename TR::DistMap DistMap;
   1.158 @@ -937,6 +923,8 @@
   1.159      typedef typename TR::ReachedMap ReachedMap;
   1.160      ///\brief The type of the map that indicates which nodes are processed.
   1.161      typedef typename TR::ProcessedMap ProcessedMap;
   1.162 +    ///The type of the DFS paths
   1.163 +    typedef typename TR::Path Path;
   1.164  
   1.165    public:
   1.166  
   1.167 @@ -947,51 +935,70 @@
   1.168  
   1.169      /// Constructor that requires parameters.
   1.170      /// These parameters will be the default values for the traits class.
   1.171 -    DfsWizard(const Digraph &g, Node s=INVALID) :
   1.172 -      TR(g,s) {}
   1.173 +    /// \param g The digraph the algorithm runs on.
   1.174 +    DfsWizard(const Digraph &g) :
   1.175 +      TR(g) {}
   1.176  
   1.177      ///Copy constructor
   1.178      DfsWizard(const TR &b) : TR(b) {}
   1.179  
   1.180      ~DfsWizard() {}
   1.181  
   1.182 -    ///Runs DFS algorithm from a source node.
   1.183 +    ///Runs DFS algorithm from the given source node.
   1.184  
   1.185 -    ///Runs DFS algorithm from a source node.
   1.186 -    ///The node can be given with the \ref source() function.
   1.187 +    ///This method runs DFS algorithm from node \c s
   1.188 +    ///in order to compute the DFS path to each node.
   1.189 +    void run(Node s)
   1.190 +    {
   1.191 +      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
   1.192 +      if (Base::_pred)
   1.193 +        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
   1.194 +      if (Base::_dist)
   1.195 +        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
   1.196 +      if (Base::_reached)
   1.197 +        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
   1.198 +      if (Base::_processed)
   1.199 +        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
   1.200 +      if (s!=INVALID)
   1.201 +        alg.run(s);
   1.202 +      else
   1.203 +        alg.run();
   1.204 +    }
   1.205 +
   1.206 +    ///Finds the DFS path between \c s and \c t.
   1.207 +
   1.208 +    ///This method runs DFS algorithm from node \c s
   1.209 +    ///in order to compute the DFS path to node \c t
   1.210 +    ///(it stops searching when \c t is processed).
   1.211 +    ///
   1.212 +    ///\return \c true if \c t is reachable form \c s.
   1.213 +    bool run(Node s, Node t)
   1.214 +    {
   1.215 +      if (s==INVALID || t==INVALID) throw UninitializedParameter();
   1.216 +      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
   1.217 +      if (Base::_pred)
   1.218 +        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
   1.219 +      if (Base::_dist)
   1.220 +        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
   1.221 +      if (Base::_reached)
   1.222 +        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
   1.223 +      if (Base::_processed)
   1.224 +        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
   1.225 +      alg.run(s,t);
   1.226 +      if (Base::_path)
   1.227 +        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
   1.228 +      if (Base::_di)
   1.229 +        *Base::_di = alg.dist(t);
   1.230 +      return alg.reached(t);
   1.231 +      }
   1.232 +
   1.233 +    ///Runs DFS algorithm to visit all nodes in the digraph.
   1.234 +
   1.235 +    ///This method runs DFS algorithm in order to compute
   1.236 +    ///the DFS path to each node.
   1.237      void run()
   1.238      {
   1.239 -      if(Base::_source==INVALID) throw UninitializedParameter();
   1.240 -      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
   1.241 -      if(Base::_reached)
   1.242 -        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
   1.243 -      if(Base::_processed)
   1.244 -        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
   1.245 -      if(Base::_pred)
   1.246 -        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
   1.247 -      if(Base::_dist)
   1.248 -        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
   1.249 -      alg.run(Base::_source);
   1.250 -    }
   1.251 -
   1.252 -    ///Runs DFS algorithm from the given node.
   1.253 -
   1.254 -    ///Runs DFS algorithm from the given node.
   1.255 -    ///\param s is the given source.
   1.256 -    void run(Node s)
   1.257 -    {
   1.258 -      Base::_source=s;
   1.259 -      run();
   1.260 -    }
   1.261 -
   1.262 -    /// Sets the source node, from which the Dfs algorithm runs.
   1.263 -
   1.264 -    /// Sets the source node, from which the Dfs algorithm runs.
   1.265 -    /// \param s is the source node.
   1.266 -    DfsWizard<TR> &source(Node s)
   1.267 -    {
   1.268 -      Base::_source=s;
   1.269 -      return *this;
   1.270 +      run(INVALID);
   1.271      }
   1.272  
   1.273      template<class T>
   1.274 @@ -1000,10 +1007,10 @@
   1.275        static PredMap *createPredMap(const Digraph &) { return 0; };
   1.276        SetPredMapBase(const TR &b) : TR(b) {}
   1.277      };
   1.278 -    ///\brief \ref named-templ-param "Named parameter"
   1.279 +    ///\brief \ref named-func-param "Named parameter"
   1.280      ///for setting \ref PredMap object.
   1.281      ///
   1.282 -    ///\ref named-templ-param "Named parameter"
   1.283 +    ///\ref named-func-param "Named parameter"
   1.284      ///for setting \ref PredMap object.
   1.285      template<class T>
   1.286      DfsWizard<SetPredMapBase<T> > predMap(const T &t)
   1.287 @@ -1018,10 +1025,10 @@
   1.288        static ReachedMap *createReachedMap(const Digraph &) { return 0; };
   1.289        SetReachedMapBase(const TR &b) : TR(b) {}
   1.290      };
   1.291 -    ///\brief \ref named-templ-param "Named parameter"
   1.292 +    ///\brief \ref named-func-param "Named parameter"
   1.293      ///for setting \ref ReachedMap object.
   1.294      ///
   1.295 -    /// \ref named-templ-param "Named parameter"
   1.296 +    /// \ref named-func-param "Named parameter"
   1.297      ///for setting \ref ReachedMap object.
   1.298      template<class T>
   1.299      DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
   1.300 @@ -1031,15 +1038,33 @@
   1.301      }
   1.302  
   1.303      template<class T>
   1.304 +    struct SetDistMapBase : public Base {
   1.305 +      typedef T DistMap;
   1.306 +      static DistMap *createDistMap(const Digraph &) { return 0; };
   1.307 +      SetDistMapBase(const TR &b) : TR(b) {}
   1.308 +    };
   1.309 +    ///\brief \ref named-func-param "Named parameter"
   1.310 +    ///for setting \ref DistMap object.
   1.311 +    ///
   1.312 +    /// \ref named-func-param "Named parameter"
   1.313 +    ///for setting \ref DistMap object.
   1.314 +    template<class T>
   1.315 +    DfsWizard<SetDistMapBase<T> > distMap(const T &t)
   1.316 +    {
   1.317 +      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
   1.318 +      return DfsWizard<SetDistMapBase<T> >(*this);
   1.319 +    }
   1.320 +
   1.321 +    template<class T>
   1.322      struct SetProcessedMapBase : public Base {
   1.323        typedef T ProcessedMap;
   1.324        static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
   1.325        SetProcessedMapBase(const TR &b) : TR(b) {}
   1.326      };
   1.327 -    ///\brief \ref named-templ-param "Named parameter"
   1.328 +    ///\brief \ref named-func-param "Named parameter"
   1.329      ///for setting \ref ProcessedMap object.
   1.330      ///
   1.331 -    /// \ref named-templ-param "Named parameter"
   1.332 +    /// \ref named-func-param "Named parameter"
   1.333      ///for setting \ref ProcessedMap object.
   1.334      template<class T>
   1.335      DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
   1.336 @@ -1049,47 +1074,60 @@
   1.337      }
   1.338  
   1.339      template<class T>
   1.340 -    struct SetDistMapBase : public Base {
   1.341 -      typedef T DistMap;
   1.342 -      static DistMap *createDistMap(const Digraph &) { return 0; };
   1.343 -      SetDistMapBase(const TR &b) : TR(b) {}
   1.344 +    struct SetPathBase : public Base {
   1.345 +      typedef T Path;
   1.346 +      SetPathBase(const TR &b) : TR(b) {}
   1.347      };
   1.348 -    ///\brief \ref named-templ-param "Named parameter"
   1.349 -    ///for setting \ref DistMap object.
   1.350 +    ///\brief \ref named-func-param "Named parameter"
   1.351 +    ///for getting the DFS path to the target node.
   1.352      ///
   1.353 -    ///\ref named-templ-param "Named parameter"
   1.354 -    ///for setting \ref DistMap object.
   1.355 +    ///\ref named-func-param "Named parameter"
   1.356 +    ///for getting the DFS path to the target node.
   1.357      template<class T>
   1.358 -    DfsWizard<SetDistMapBase<T> > distMap(const T &t)
   1.359 +    DfsWizard<SetPathBase<T> > path(const T &t)
   1.360      {
   1.361 -      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
   1.362 -      return DfsWizard<SetDistMapBase<T> >(*this);
   1.363 +      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
   1.364 +      return DfsWizard<SetPathBase<T> >(*this);
   1.365 +    }
   1.366 +
   1.367 +    ///\brief \ref named-func-param "Named parameter"
   1.368 +    ///for getting the distance of the target node.
   1.369 +    ///
   1.370 +    ///\ref named-func-param "Named parameter"
   1.371 +    ///for getting the distance of the target node.
   1.372 +    DfsWizard dist(const int &d)
   1.373 +    {
   1.374 +      Base::_di=const_cast<int*>(&d);
   1.375 +      return *this;
   1.376      }
   1.377  
   1.378    };
   1.379  
   1.380 -  ///Function type interface for Dfs algorithm.
   1.381 +  ///Function-type interface for DFS algorithm.
   1.382  
   1.383    ///\ingroup search
   1.384 -  ///Function type interface for Dfs algorithm.
   1.385 +  ///Function-type interface for DFS algorithm.
   1.386    ///
   1.387 -  ///This function also has several
   1.388 -  ///\ref named-templ-func-param "named parameters",
   1.389 +  ///This function also has several \ref named-func-param "named parameters",
   1.390    ///they are declared as the members of class \ref DfsWizard.
   1.391 -  ///The following
   1.392 -  ///example shows how to use these parameters.
   1.393 +  ///The following examples show how to use these parameters.
   1.394    ///\code
   1.395 -  ///  dfs(g,source).predMap(preds).run();
   1.396 +  ///  // Compute the DFS tree
   1.397 +  ///  dfs(g).predMap(preds).distMap(dists).run(s);
   1.398 +  ///
   1.399 +  ///  // Compute the DFS path from s to t
   1.400 +  ///  bool reached = dfs(g).path(p).dist(d).run(s,t);
   1.401    ///\endcode
   1.402 +
   1.403    ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
   1.404    ///to the end of the parameter list.
   1.405    ///\sa DfsWizard
   1.406    ///\sa Dfs
   1.407    template<class GR>
   1.408    DfsWizard<DfsWizardBase<GR> >
   1.409 -  dfs(const GR &g,typename GR::Node s=INVALID)
   1.410 +  dfs(const GR &digraph)
   1.411    {
   1.412 -    return DfsWizard<DfsWizardBase<GR> >(g,s);
   1.413 +    return DfsWizard<DfsWizardBase<GR> >(digraph);
   1.414    }
   1.415  
   1.416  #ifdef DOXYGEN