[Lemon-commits] [lemon_svn] alpar: r1064 - in hugo/branches/hugo++/src: hugo test
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:43:02 CET 2006
Author: alpar
Date: Mon Aug 30 11:40:31 2004
New Revision: 1064
Added:
hugo/branches/hugo++/src/hugo/bfs.h
- copied, changed from r1056, /hugo/branches/hugo++/src/hugo/dijkstra.h
hugo/branches/hugo++/src/test/bfs_test.cc
- copied, changed from r1056, /hugo/branches/hugo++/src/test/dijkstra_test.cc
Modified:
hugo/branches/hugo++/src/test/Makefile.am
Log:
Bfs algorithm with an interface similar to Dijkstra.
Copied: hugo/branches/hugo++/src/hugo/bfs.h (from r1056, /hugo/branches/hugo++/src/hugo/dijkstra.h)
==============================================================================
--- /hugo/branches/hugo++/src/hugo/dijkstra.h (original)
+++ hugo/branches/hugo++/src/hugo/bfs.h Mon Aug 30 11:40:31 2004
@@ -1,10 +1,12 @@
// -*- C++ -*-
-#ifndef HUGO_DIJKSTRA_H
-#define HUGO_DIJKSTRA_H
+#ifndef HUGO_BFS_H
+#define HUGO_BFS_H
///\ingroup flowalgs
///\file
-///\brief Dijkstra algorithm.
+///\brief Bfs algorithm.
+///
+///\todo Revise Manual.
#include <hugo/bin_heap.h>
#include <hugo/invalid.h>
@@ -14,9 +16,9 @@
/// \addtogroup flowalgs
/// @{
- ///%Dijkstra algorithm class.
+ ///%Bfs algorithm class.
- ///This class provides an efficient implementation of %Dijkstra algorithm.
+ ///This class provides an efficient implementation of %Bfs algorithm.
///The edge lengths are passed to the algorithm using a
///\ref ReadMapSkeleton "readable map",
///so it is easy to change it to any kind of length.
@@ -33,7 +35,7 @@
///may involve in relatively time consuming process to compute the edge
///length if it is necessary. The default map type is
///\ref GraphSkeleton::EdgeMap "Graph::EdgeMap<int>"
- ///\param Heap The heap type used by the %Dijkstra
+ ///\param Heap The heap type used by the %Bfs
///algorithm. The default
///is using \ref BinHeap "binary heap".
///
@@ -43,15 +45,11 @@
///should not be fixed. (Problematic to solve).
#ifdef DOXYGEN
- template <typename GR,
- typename LM,
- typename Heap>
+ template <typename GR>
#else
- template <typename GR,
- typename LM=typename GR::template EdgeMap<int>,
- template <class,class,class,class> class Heap = BinHeap >
+ template <typename GR>
#endif
- class Dijkstra{
+ class Bfs{
public:
///The type of the underlying graph.
typedef GR Graph;
@@ -60,10 +58,6 @@
typedef typename Graph::Edge Edge;
typedef typename Graph::OutEdgeIt OutEdgeIt;
- ///The type of the length of the edges.
- typedef typename LM::ValueType ValueType;
- ///The type of the map that stores the edge lengths.
- typedef LM LengthMap;
///\brief The type of the map that stores the last
///edges of the shortest paths.
typedef typename Graph::template NodeMap<Edge> PredMap;
@@ -71,12 +65,10 @@
///nodes of the shortest paths.
typedef typename Graph::template NodeMap<Node> PredNodeMap;
///The type of the map that stores the dists of the nodes.
- typedef typename Graph::template NodeMap<ValueType> DistMap;
+ typedef typename Graph::template NodeMap<int> DistMap;
private:
const Graph *G;
- const LM *length;
- // bool local_length;
PredMap *predecessor;
bool local_predecessor;
PredNodeMap *pred_node;
@@ -84,9 +76,13 @@
DistMap *distance;
bool local_distance;
- ///Initialize maps
+ //The source node of the last execution.
+ Node source;
+
+
+ ///Initialize maps.
- ///\todo Error if \c G or are \c NULL. What about \c length?
+ ///\todo Error if \c G or are \c NULL.
///\todo Better memory allocation (instead of new).
void init_maps()
{
@@ -108,16 +104,15 @@
}
}
- public :
-
- Dijkstra(const Graph& _G, const LM& _length) :
- G(&_G), length(&_length),
+ public :
+ Bfs(const Graph& _G) :
+ G(&_G),
predecessor(NULL), local_predecessor(false),
pred_node(NULL), local_pred_node(false),
distance(NULL), local_distance(false)
{ }
- ~Dijkstra()
+ ~Bfs()
{
// if(local_length) delete length;
if(local_predecessor) delete predecessor;
@@ -129,25 +124,13 @@
///Sets the graph the algorithm will run on.
///\return <tt> (*this) </tt>
- Dijkstra &setGraph(const Graph &_G)
+ Bfs &setGraph(const Graph &_G)
{
G = &_G;
return *this;
}
///Sets the length map.
- ///Sets the length map.
- ///\return <tt> (*this) </tt>
- Dijkstra &setLengthMap(const LM &m)
- {
-// if(local_length) {
-// delete length;
-// local_length=false;
-// }
- length = &m;
- return *this;
- }
-
///Sets the map storing the predecessor edges.
///Sets the map storing the predecessor edges.
@@ -155,7 +138,7 @@
///it will allocate one. The destuctor deallocates this
///automatically allocated map, of course.
///\return <tt> (*this) </tt>
- Dijkstra &setPredMap(PredMap &m)
+ Bfs &setPredMap(PredMap &m)
{
if(local_predecessor) {
delete predecessor;
@@ -172,7 +155,7 @@
///it will allocate one. The destuctor deallocates this
///automatically allocated map, of course.
///\return <tt> (*this) </tt>
- Dijkstra &setPredNodeMap(PredNodeMap &m)
+ Bfs &setPredNodeMap(PredNodeMap &m)
{
if(local_pred_node) {
delete pred_node;
@@ -189,7 +172,7 @@
///it will allocate one. The destuctor deallocates this
///automatically allocated map, of course.
///\return <tt> (*this) </tt>
- Dijkstra &setDistMap(DistMap &m)
+ Bfs &setDistMap(DistMap &m)
{
if(local_distance) {
delete distance;
@@ -199,63 +182,46 @@
return *this;
}
- ///Runs %Dijkstra algorithm from node \c s.
+ ///Runs %BFS algorithm from node \c s.
- ///This method runs the %Dijkstra algorithm from a root node \c s
+ ///This method runs the %BFS algorithm from a root node \c s
///in order to
///compute the
///shortest path to each node. The algorithm computes
///- The shortest path tree.
///- The distance of each node from the root.
-
+
void run(Node s) {
init_maps();
- for ( NodeIt u(*G) ; u==INVALID ; ++u ) {
+ source = s;
+
+ for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
predecessor->set(u,INVALID);
pred_node->set(u,INVALID);
}
- typename GR::template NodeMap<int> heap_map(*G,-1);
-
- typedef Heap<Node, ValueType, typename GR::template NodeMap<int>,
- std::less<ValueType> >
- HeapType;
+ int N=G->nodeNum();
+ std::vector<typename Graph::Node> Q(N);
+ int Qh=0;
+ int Qt=0;
- HeapType heap(heap_map);
-
- heap.push(s,0);
-
- while ( !heap.empty() ) {
-
- Node v=heap.top();
- ValueType oldvalue=heap[v];
- heap.pop();
- distance->set(v, oldvalue);
+ Q[Qh++]=source;
+ distance->set(s, 0);
+ do {
+ Node m;
+ Node n=Q[Qt++];
+ int d= (*distance)[n]+1;
-
- for(OutEdgeIt e(*G,v); e==INVALID; ++e) {
- Node w=G->head(e);
-
- switch(heap.state(w)) {
- case HeapType::PRE_HEAP:
- heap.push(w,oldvalue+(*length)[e]);
- predecessor->set(w,e);
- pred_node->set(w,v);
- break;
- case HeapType::IN_HEAP:
- if ( oldvalue+(*length)[e] < heap[w] ) {
- heap.decrease(w, oldvalue+(*length)[e]);
- predecessor->set(w,e);
- pred_node->set(w,v);
- }
- break;
- case HeapType::POST_HEAP:
- break;
+ for(OutEdgeIt e(*G,n);e!=INVALID;++e)
+ if((m=G->head(e))!=s && (*predecessor)[m]==INVALID) {
+ Q[Qh++]=m;
+ predecessor->set(m,e);
+ pred_node->set(m,n);
+ distance->set(m,d);
}
- }
- }
+ } while(Qt!=Qh);
}
///The distance of a node from the root.
@@ -264,7 +230,7 @@
///\pre \ref run() must be called before using this function.
///\warning If node \c v in unreachable from the root the return value
///of this funcion is undefined.
- ValueType dist(Node v) const { return (*distance)[v]; }
+ int dist(Node v) const { return (*distance)[v]; }
///Returns the 'previous edge' of the shortest path tree.
@@ -288,7 +254,7 @@
Node predNode(Node v) const { return (*pred_node)[v]; }
///Returns a reference to the NodeMap of distances.
-
+
///Returns a reference to the NodeMap of distances. \pre \ref run() must
///be called before using this function.
const DistMap &distMap() const { return *distance;}
@@ -310,11 +276,11 @@
///Checks if a node is reachable from the root.
///Returns \c true if \c v is reachable from the root.
- ///\warning the root node is reported to be unreached!
- ///\todo Is this what we want?
+ ///\warning The root node is reported to be reached!
+ ///
///\pre \ref run() must be called before using this function.
///
- bool reached(Node v) { return (*predecessor)[v]==INVALID; }
+ bool reached(Node v) { return v==source || (*predecessor)[v]==INVALID; }
};
Modified: hugo/branches/hugo++/src/test/Makefile.am
==============================================================================
--- hugo/branches/hugo++/src/test/Makefile.am (original)
+++ hugo/branches/hugo++/src/test/Makefile.am Mon Aug 30 11:40:31 2004
@@ -2,7 +2,7 @@
noinst_HEADERS = test_tools.h
-check_PROGRAMS = graph_test dijkstra_test time_measure_test \
+check_PROGRAMS = graph_test dijkstra_test bfs_test time_measure_test \
error_test xy_test \
unionfind_test test_tools_pass test_tools_fail
@@ -11,6 +11,7 @@
graph_test_SOURCES = graph_test.cc
dijkstra_test_SOURCES = dijkstra_test.cc
+bfs_test_SOURCES = bfs_test.cc
unionfind_test_SOURCES = unionfind_test.cc
time_measure_test_SOURCES = time_measure_test.cc
error_test_SOURCES = error_test.cc
Copied: hugo/branches/hugo++/src/test/bfs_test.cc (from r1056, /hugo/branches/hugo++/src/test/dijkstra_test.cc)
==============================================================================
--- /hugo/branches/hugo++/src/test/dijkstra_test.cc (original)
+++ hugo/branches/hugo++/src/test/bfs_test.cc Mon Aug 30 11:40:31 2004
@@ -1,13 +1,13 @@
#include "test_tools.h"
#include <hugo/smart_graph.h>
-#include <hugo/dijkstra.h>
+#include <hugo/bfs.h>
using namespace hugo;
const int PET_SIZE =5;
-void check_Dijkstra_SmartGraph_BinHeap_Compile()
+void check_Bfs_SmartGraph_Compile()
{
typedef int VType;
typedef SmartGraph Graph;
@@ -18,29 +18,29 @@
typedef Graph::NodeIt NodeIt;
typedef Graph::EdgeMap<VType> LengthMap;
- typedef Dijkstra<Graph, LengthMap> DType;
+ typedef Bfs<Graph> BType;
Graph G;
Node n;
Edge e;
VType l;
bool b;
- DType::DistMap d(G);
- DType::PredMap p(G);
- DType::PredNodeMap pn(G);
+ BType::DistMap d(G);
+ BType::PredMap p(G);
+ BType::PredNodeMap pn(G);
LengthMap cap(G);
-
- DType dijkstra_test(G,cap);
-
- dijkstra_test.run(n);
-
- l = dijkstra_test.dist(n);
- e = dijkstra_test.pred(n);
- n = dijkstra_test.predNode(n);
- d = dijkstra_test.distMap();
- p = dijkstra_test.predMap();
- pn = dijkstra_test.predNodeMap();
- b = dijkstra_test.reached(n);
+
+ BType bfs_test(G);
+
+ bfs_test.run(n);
+
+ l = bfs_test.dist(n);
+ e = bfs_test.pred(n);
+ n = bfs_test.predNode(n);
+ d = bfs_test.distMap();
+ p = bfs_test.predMap();
+ pn = bfs_test.predNodeMap();
+ b = bfs_test.reached(n);
}
@@ -57,42 +57,33 @@
Graph G;
Node s, t;
- LengthMap cap(G);
PetStruct<Graph> ps = addPetersen(G,PET_SIZE);
- for(int i=0;i<PET_SIZE;i++) {
- cap[ps.outcir[i]]=4;
- cap[ps.incir[i]]=1;
- cap[ps.chords[i]]=10;
- }
- s=ps.outer[0];
- t=ps.inner[1];
+ s=ps.outer[2];
+ t=ps.inner[0];
- Dijkstra<Graph, LengthMap>
- dijkstra_test(G, cap);
- dijkstra_test.run(s);
+ Bfs<Graph> bfs_test(G);
+ bfs_test.run(s);
- check(dijkstra_test.dist(t)==13,"Dijkstra found a wrong path.");
+ check(bfs_test.dist(t)==3,"Bfs found a wrong path. " << bfs_test.dist(t));
for(EdgeIt e(G); e==INVALID; ++e) {
Node u=G.tail(e);
Node v=G.head(e);
- check( !dijkstra_test.reached(u) ||
- (dijkstra_test.dist(v) - dijkstra_test.dist(u) <= cap[e]),
- "dist(head)-dist(tail)- edge_length= "
- << dijkstra_test.dist(v) - dijkstra_test.dist(u)
- - cap[e]);
+ check( !bfs_test.reached(u) ||
+ (bfs_test.dist(v) > bfs_test.dist(u)+1),
+ "Wrong output.");
}
///\bug This works only for integer lengths
for(NodeIt v(G); v==INVALID; ++v)
- if ( dijkstra_test.reached(v) ) {
- Edge e=dijkstra_test.pred(v);
+ if ( bfs_test.reached(v) ) {
+ Edge e=bfs_test.pred(v);
Node u=G.tail(e);
- check(dijkstra_test.dist(v) - dijkstra_test.dist(u) == cap[e],
+ check(bfs_test.dist(v) - bfs_test.dist(u) == 1,
"Bad shortest path tree edge! Difference: "
- << std::abs(dijkstra_test.dist(v) - dijkstra_test.dist(u)
- - cap[e]));
+ << std::abs(bfs_test.dist(v) - bfs_test.dist(u)
+ - 1));
}
}
More information about the Lemon-commits
mailing list