[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