[Lemon-commits] Peter Kovacs: Improve the function-type interfac...
Lemon HG
hg at lemon.cs.elte.hu
Wed Sep 24 16:20:20 CEST 2008
details: http://lemon.cs.elte.hu/hg/lemon/rev/931190050520
changeset: 278:931190050520
user: Peter Kovacs <kpeter [at] inf.elte.hu>
date: Mon Sep 22 15:33:23 2008 +0200
description:
Improve the function-type interface of bfs, dfs, and dijkstra
(ticket #96)
- BfsWizard and DfsWizard have run(s), run(s,t), and run() functions,
DijkstraWizard has run(s) and run(s,t) functions.
- Set NodeMap<T> instead of NullMap as PredMap and DistMap in the
default traits classes for the function-type interface.
- Modify the related test files.
- Doc improvements.
- Bug fix in concepts/path.h.
diffstat:
7 files changed, 488 insertions(+), 338 deletions(-)
lemon/bfs.h | 248 +++++++++++++++++++++++++++---------------------
lemon/concepts/path.h | 5
lemon/dfs.h | 252 ++++++++++++++++++++++++++++---------------------
lemon/dijkstra.h | 226 ++++++++++++++++++++++++-------------------
test/bfs_test.cc | 39 +++++--
test/dfs_test.cc | 32 +++++-
test/dijkstra_test.cc | 24 ++--
diffs (truncated from 1447 to 300 lines):
diff -r c691064dfd4f -r 931190050520 lemon/bfs.h
--- a/lemon/bfs.h Thu Sep 11 11:10:44 2008 +0100
+++ b/lemon/bfs.h Mon Sep 22 15:33:23 2008 +0200
@@ -28,6 +28,7 @@
#include <lemon/core.h>
#include <lemon/error.h>
#include <lemon/maps.h>
+#include <lemon/path.h>
namespace lemon {
@@ -115,7 +116,7 @@
///\ingroup search
///This class provides an efficient implementation of the %BFS algorithm.
///
- ///There is also a \ref bfs() "function type interface" for the BFS
+ ///There is also a \ref bfs() "function-type interface" for the BFS
///algorithm, which is convenient in the simplier cases and it can be
///used easier.
///
@@ -841,26 +842,23 @@
///The type of the map that stores the predecessor
///arcs of the shortest paths.
///It must meet the \ref concepts::WriteMap "WriteMap" concept.
- typedef NullMap<typename Digraph::Node,typename Digraph::Arc> PredMap;
+ typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
///Instantiates a \ref PredMap.
///This function instantiates a \ref PredMap.
///\param g is the digraph, to which we would like to define the
///\ref PredMap.
///\todo The digraph alone may be insufficient to initialize
-#ifdef DOXYGEN
static PredMap *createPredMap(const Digraph &g)
-#else
- static PredMap *createPredMap(const Digraph &)
-#endif
{
- return new PredMap();
+ return new PredMap(g);
}
///The type of the map that indicates which nodes are processed.
///The type of the map that indicates which nodes are processed.
///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+ ///By default it is a NullMap.
typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
///Instantiates a \ref ProcessedMap.
@@ -895,21 +893,22 @@
///The type of the map that stores the distances of the nodes.
///It must meet the \ref concepts::WriteMap "WriteMap" concept.
- ///
- typedef NullMap<typename Digraph::Node,int> DistMap;
+ typedef typename Digraph::template NodeMap<int> DistMap;
///Instantiates a \ref DistMap.
///This function instantiates a \ref DistMap.
///\param g is the digraph, to which we would like to define
///the \ref DistMap
-#ifdef DOXYGEN
static DistMap *createDistMap(const Digraph &g)
-#else
- static DistMap *createDistMap(const Digraph &)
-#endif
{
- return new DistMap();
+ return new DistMap(g);
}
+
+ ///The type of the shortest paths.
+
+ ///The type of the shortest paths.
+ ///It must meet the \ref concepts::Path "Path" concept.
+ typedef lemon::Path<Digraph> Path;
};
/// Default traits class used by \ref BfsWizard
@@ -939,51 +938,39 @@
void *_pred;
//Pointer to the map of distances.
void *_dist;
- //Pointer to the source node.
- Node _source;
+ //Pointer to the shortest path to the target node.
+ void *_path;
+ //Pointer to the distance of the target node.
+ int *_di;
public:
/// Constructor.
/// This constructor does not require parameters, therefore it initiates
- /// all of the attributes to default values (0, INVALID).
+ /// all of the attributes to \c 0.
BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
- _dist(0), _source(INVALID) {}
+ _dist(0), _path(0), _di(0) {}
/// Constructor.
- /// This constructor requires some parameters,
- /// listed in the parameters list.
- /// Others are initiated to 0.
+ /// This constructor requires one parameter,
+ /// others are initiated to \c 0.
/// \param g The digraph the algorithm runs on.
- /// \param s The source node.
- BfsWizardBase(const GR &g, Node s=INVALID) :
+ BfsWizardBase(const GR &g) :
_g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
- _reached(0), _processed(0), _pred(0), _dist(0), _source(s) {}
+ _reached(0), _processed(0), _pred(0), _dist(0), _path(0), _di(0) {}
};
- /// Auxiliary class for the function type interface of BFS algorithm.
+ /// Auxiliary class for the function-type interface of BFS algorithm.
- /// This auxiliary class is created to implement the function type
- /// interface of \ref Bfs algorithm. It uses the functions and features
- /// of the plain \ref Bfs, but it is much simpler to use it.
- /// It should only be used through the \ref bfs() function, which makes
- /// it easier to use the algorithm.
+ /// This auxiliary class is created to implement the
+ /// \ref bfs() "function-type interface" of \ref Bfs algorithm.
+ /// It does not have own \ref run() method, it uses the functions
+ /// and features of the plain \ref Bfs.
///
- /// Simplicity means that the way to change the types defined
- /// in the traits class is based on functions that returns the new class
- /// and not on templatable built-in classes.
- /// When using the plain \ref Bfs
- /// the new class with the modified type comes from
- /// the original class by using the ::
- /// operator. In the case of \ref BfsWizard only
- /// a function have to be called, and it will
- /// return the needed class.
- ///
- /// It does not have own \ref run() method. When its \ref run() method
- /// is called, it initiates a plain \ref Bfs object, and calls the
- /// \ref Bfs::run() method of it.
+ /// This class should only be used through the \ref bfs() function,
+ /// which makes it easier to use the algorithm.
template<class TR>
class BfsWizard : public TR
{
@@ -1006,6 +993,8 @@
typedef typename TR::ReachedMap ReachedMap;
///\brief The type of the map that indicates which nodes are processed.
typedef typename TR::ProcessedMap ProcessedMap;
+ ///The type of the shortest paths
+ typedef typename TR::Path Path;
public:
@@ -1016,51 +1005,70 @@
/// Constructor that requires parameters.
/// These parameters will be the default values for the traits class.
- BfsWizard(const Digraph &g, Node s=INVALID) :
- TR(g,s) {}
+ /// \param g The digraph the algorithm runs on.
+ BfsWizard(const Digraph &g) :
+ TR(g) {}
///Copy constructor
BfsWizard(const TR &b) : TR(b) {}
~BfsWizard() {}
- ///Runs BFS algorithm from a source node.
+ ///Runs BFS algorithm from the given source node.
- ///Runs BFS algorithm from a source node.
- ///The node can be given with the \ref source() function.
+ ///This method runs BFS algorithm from node \c s
+ ///in order to compute the shortest path to each node.
+ void run(Node s)
+ {
+ Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
+ if (Base::_pred)
+ alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+ if (Base::_dist)
+ alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+ if (Base::_reached)
+ alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
+ if (Base::_processed)
+ alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
+ if (s!=INVALID)
+ alg.run(s);
+ else
+ alg.run();
+ }
+
+ ///Finds the shortest path between \c s and \c t.
+
+ ///This method runs BFS algorithm from node \c s
+ ///in order to compute the shortest path to node \c t
+ ///(it stops searching when \c t is processed).
+ ///
+ ///\return \c true if \c t is reachable form \c s.
+ bool run(Node s, Node t)
+ {
+ if (s==INVALID || t==INVALID) throw UninitializedParameter();
+ Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
+ if (Base::_pred)
+ alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+ if (Base::_dist)
+ alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+ if (Base::_reached)
+ alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
+ if (Base::_processed)
+ alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
+ alg.run(s,t);
+ if (Base::_path)
+ *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
+ if (Base::_di)
+ *Base::_di = alg.dist(t);
+ return alg.reached(t);
+ }
+
+ ///Runs BFS algorithm to visit all nodes in the digraph.
+
+ ///This method runs BFS algorithm in order to compute
+ ///the shortest path to each node.
void run()
{
- if(Base::_source==INVALID) throw UninitializedParameter();
- Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
- if(Base::_reached)
- alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
- if(Base::_processed)
- alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
- if(Base::_pred)
- alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
- if(Base::_dist)
- alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
- alg.run(Base::_source);
- }
-
- ///Runs BFS algorithm from the given node.
-
- ///Runs BFS algorithm from the given node.
- ///\param s is the given source.
- void run(Node s)
- {
- Base::_source=s;
- run();
- }
-
- /// Sets the source node, from which the Bfs algorithm runs.
-
- /// Sets the source node, from which the Bfs algorithm runs.
- /// \param s is the source node.
- BfsWizard<TR> &source(Node s)
- {
- Base::_source=s;
- return *this;
+ run(INVALID);
}
template<class T>
@@ -1069,10 +1077,10 @@
static PredMap *createPredMap(const Digraph &) { return 0; };
SetPredMapBase(const TR &b) : TR(b) {}
};
- ///\brief \ref named-templ-param "Named parameter"
+ ///\brief \ref named-func-param "Named parameter"
///for setting \ref PredMap object.
///
- /// \ref named-templ-param "Named parameter"
+ ///\ref named-func-param "Named parameter"
///for setting \ref PredMap object.
template<class T>
BfsWizard<SetPredMapBase<T> > predMap(const T &t)
@@ -1087,10 +1095,10 @@
static ReachedMap *createReachedMap(const Digraph &) { return 0; };
SetReachedMapBase(const TR &b) : TR(b) {}
};
- ///\brief \ref named-templ-param "Named parameter"
+ ///\brief \ref named-func-param "Named parameter"
///for setting \ref ReachedMap object.
///
- /// \ref named-templ-param "Named parameter"
+ /// \ref named-func-param "Named parameter"
///for setting \ref ReachedMap object.
template<class T>
BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
@@ -1100,15 +1108,33 @@
}
template<class T>
+ struct SetDistMapBase : public Base {
+ typedef T DistMap;
+ static DistMap *createDistMap(const Digraph &) { return 0; };
+ SetDistMapBase(const TR &b) : TR(b) {}
+ };
More information about the Lemon-commits
mailing list