src/work/deba/dijkstra.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000
changeset 822 88226d9fe821
parent 694 2d87cefb35b2
child 880 9d0bfd35b97c
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

Some macros and comments has been changed.
     1 // -*- C++ -*-
     2 #ifndef HUGO_DIJKSTRA_H
     3 #define HUGO_DIJKSTRA_H
     4 
     5 ///\ingroup galgs
     6 ///\file
     7 ///\brief Dijkstra algorithm.
     8 
     9 #include <hugo/bin_heap.h>
    10 #include <hugo/invalid.h>
    11 
    12 namespace hugo {
    13 
    14 /// \addtogroup galgs
    15 /// @{
    16 
    17   ///%Dijkstra algorithm class.
    18 
    19   ///This class provides an efficient implementation of %Dijkstra algorithm.
    20   ///The edge lengths are passed to the algorithm using a
    21   ///\ref ReadMapSkeleton "readable map",
    22   ///so it is easy to change it to any kind of length.
    23   ///
    24   ///The type of the length is determined by the \c ValueType of the length map.
    25   ///
    26   ///It is also possible to change the underlying priority heap.
    27   ///
    28   ///\param GR The graph type the algorithm runs on.
    29   ///\param LM This read-only
    30   ///EdgeMap
    31   ///determines the
    32   ///lengths of the edges. It is read once for each edge, so the map
    33   ///may involve in relatively time consuming process to compute the edge
    34   ///length if it is necessary. The default map type is
    35   ///\ref GraphSkeleton::EdgeMap "Graph::EdgeMap<int>"
    36   ///\param Heap The heap type used by the %Dijkstra
    37   ///algorithm. The default
    38   ///is using \ref BinHeap "binary heap".
    39   ///
    40   ///\author Jacint Szabo and Alpar Juttner
    41   ///\todo We need a typedef-names should be standardized. (-:
    42 
    43 #ifdef DOXYGEN
    44   template <typename GR,
    45 	    typename LM,
    46 	    typename Heap>
    47 #else
    48   template <typename GR,
    49 	    typename LM=typename GR::template EdgeMap<int>,
    50 	    template <class,class,class,class> class Heap = BinHeap >
    51 #endif
    52   class Dijkstra{
    53   public:
    54     ///The type of the underlying graph.
    55     typedef GR Graph;
    56     typedef typename Graph::Node Node;
    57     typedef typename Graph::NodeIt NodeIt;
    58     typedef typename Graph::Edge Edge;
    59     typedef typename Graph::OutEdgeIt OutEdgeIt;
    60     
    61     ///The type of the length of the edges.
    62     typedef typename LM::ValueType ValueType;
    63     ///The type of the map that stores the edge lengths.
    64     typedef LM LengthMap;
    65     ///\brief The type of the map that stores the last
    66     ///edges of the shortest paths.
    67     typedef typename Graph::template NodeMap<Edge> PredMap;
    68     ///\brief The type of the map that stores the last but one
    69     ///nodes of the shortest paths.
    70     typedef typename Graph::template NodeMap<Node> PredNodeMap;
    71     ///The type of the map that stores the dists of the nodes.
    72     typedef typename Graph::template NodeMap<ValueType> DistMap;
    73 
    74   private:
    75     const Graph *G;
    76     const LM *length;
    77     //    bool local_length;
    78     PredMap *predecessor;
    79     bool local_predecessor;
    80     PredNodeMap *pred_node;
    81     bool local_pred_node;
    82     DistMap *distance;
    83     bool local_distance;
    84 
    85     ///Initialize maps
    86     
    87     ///\todo Error if \c G or are \c NULL. What about \c length?
    88     ///\todo Better memory allocation (instead of new).
    89     void init_maps() 
    90     {
    91 //       if(!length) {
    92 // 	local_length = true;
    93 // 	length = new LM(G);
    94 //       }
    95       if(!predecessor) {
    96 	local_predecessor = true;
    97 	predecessor = new PredMap(*G);
    98       }
    99       if(!pred_node) {
   100 	local_pred_node = true;
   101 	pred_node = new PredNodeMap(*G);
   102       }
   103       if(!distance) {
   104 	local_distance = true;
   105 	distance = new DistMap(*G);
   106       }
   107     }
   108     
   109   public :
   110     
   111     Dijkstra(const Graph& _G, const LM& _length) :
   112       G(&_G), length(&_length),
   113       predecessor(NULL), pred_node(NULL), distance(NULL),
   114       local_predecessor(false), local_pred_node(false), local_distance(false)
   115     { }
   116     
   117     ~Dijkstra() 
   118     {
   119       //      if(local_length) delete length;
   120       if(local_predecessor) delete predecessor;
   121       if(local_pred_node) delete pred_node;
   122       if(local_distance) delete distance;
   123     }
   124 
   125     ///Sets the graph the algorithm will run on.
   126 
   127     ///Sets the graph the algorithm will run on.
   128     ///\return <tt> (*this) </tt>
   129     Dijkstra &setGraph(const Graph &_G) 
   130     {
   131       G = &_G;
   132       return *this;
   133     }
   134     ///Sets the length map.
   135 
   136     ///Sets the length map.
   137     ///\return <tt> (*this) </tt>
   138     Dijkstra &setLengthMap(const LM &m) 
   139     {
   140 //       if(local_length) {
   141 // 	delete length;
   142 // 	local_length=false;
   143 //       }
   144       length = &m;
   145       return *this;
   146     }
   147 
   148     ///Sets the map storing the predecessor edges.
   149 
   150     ///Sets the map storing the predecessor edges.
   151     ///If you don't use this function before calling \ref run(),
   152     ///it will allocate one. The destuctor deallocates this
   153     ///automatically allocated map, of course.
   154     ///\return <tt> (*this) </tt>
   155     Dijkstra &setPredMap(PredMap &m) 
   156     {
   157       if(local_predecessor) {
   158 	delete predecessor;
   159 	local_predecessor=false;
   160       }
   161       predecessor = &m;
   162       return *this;
   163     }
   164 
   165     ///Sets the map storing the predecessor nodes.
   166 
   167     ///Sets the map storing the predecessor nodes.
   168     ///If you don't use this function before calling \ref run(),
   169     ///it will allocate one. The destuctor deallocates this
   170     ///automatically allocated map, of course.
   171     ///\return <tt> (*this) </tt>
   172     Dijkstra &setPredNodeMap(PredNodeMap &m) 
   173     {
   174       if(local_pred_node) {
   175 	delete pred_node;
   176 	local_pred_node=false;
   177       }
   178       pred_node = &m;
   179       return *this;
   180     }
   181 
   182     ///Sets the map storing the distances calculated by the algorithm.
   183 
   184     ///Sets the map storing the distances calculated by the algorithm.
   185     ///If you don't use this function before calling \ref run(),
   186     ///it will allocate one. The destuctor deallocates this
   187     ///automatically allocated map, of course.
   188     ///\return <tt> (*this) </tt>
   189     Dijkstra &setDistMap(DistMap &m) 
   190     {
   191       if(local_distance) {
   192 	delete distance;
   193 	local_distance=false;
   194       }
   195       distance = &m;
   196       return *this;
   197     }
   198     
   199   ///Runs %Dijkstra algorithm from node \c s.
   200 
   201   ///This method runs the %Dijkstra algorithm from a root node \c s
   202   ///in order to
   203   ///compute the
   204   ///shortest path to each node. The algorithm computes
   205   ///- The shortest path tree.
   206   ///- The distance of each node from the root.
   207     
   208     void run(Node s) {
   209       
   210       init_maps();
   211       
   212       for ( NodeIt u(*G) ; G->valid(u) ; G->next(u) ) {
   213 	predecessor->set(u,INVALID);
   214 	pred_node->set(u,INVALID);
   215       }
   216       
   217       typename GR::template NodeMap<int> heap_map(*G,-1);
   218       
   219       typedef Heap<Node, ValueType, typename GR::template NodeMap<int>,
   220       std::less<ValueType> > 
   221       HeapType;
   222       
   223       HeapType heap(heap_map);
   224       
   225       heap.push(s,0); 
   226       
   227       while ( !heap.empty() ) {
   228 	
   229 	Node v=heap.top(); 
   230 	ValueType oldvalue=heap[v];
   231 	heap.pop();
   232 	distance->set(v, oldvalue);
   233 	
   234 	
   235 	for(OutEdgeIt e(*G,v); G->valid(e); G->next(e)) {
   236 	  Node w=G->bNode(e); 
   237 	  
   238 	  switch(heap.state(w)) {
   239 	  case HeapType::PRE_HEAP:
   240 	    heap.push(w,oldvalue+(*length)[e]); 
   241 	    predecessor->set(w,e);
   242 	    pred_node->set(w,v);
   243 	    break;
   244 	  case HeapType::IN_HEAP:
   245 	    if ( oldvalue+(*length)[e] < heap[w] ) {
   246 	      heap.decrease(w, oldvalue+(*length)[e]); 
   247 	      predecessor->set(w,e);
   248 	      pred_node->set(w,v);
   249 	    }
   250 	    break;
   251 	  case HeapType::POST_HEAP:
   252 	    break;
   253 	  }
   254 	}
   255       }
   256     }
   257     
   258     ///The distance of a node from the root.
   259 
   260     ///Returns the distance of a node from the root.
   261     ///\pre \ref run() must be called before using this function.
   262     ///\warning If node \c v in unreachable from the root the return value
   263     ///of this funcion is undefined.
   264     ValueType dist(Node v) const { return (*distance)[v]; }
   265 
   266     ///Returns the 'previous edge' of the shortest path tree.
   267 
   268     ///For a node \c v it returns the 'previous edge' of the shortest path tree,
   269     ///i.e. it returns the last edge from a shortest path from the root to \c
   270     ///v. It is \ref INVALID
   271     ///if \c v is unreachable from the root or if \c v=s. The
   272     ///shortest path tree used here is equal to the shortest path tree used in
   273     ///\ref predNode(Node v).  \pre \ref run() must be called before using
   274     ///this function.
   275     Edge pred(Node v) const { return (*predecessor)[v]; }
   276 
   277     ///Returns the 'previous node' of the shortest path tree.
   278 
   279     ///For a node \c v it returns the 'previous node' of the shortest path tree,
   280     ///i.e. it returns the last but one node from a shortest path from the
   281     ///root to \c /v. It is INVALID if \c v is unreachable from the root or if
   282     ///\c v=s. The shortest path tree used here is equal to the shortest path
   283     ///tree used in \ref pred(Node v).  \pre \ref run() must be called before
   284     ///using this function.
   285     Node predNode(Node v) const { return (*pred_node)[v]; }
   286     
   287     ///Returns a reference to the NodeMap of distances.
   288 
   289     ///Returns a reference to the NodeMap of distances. \pre \ref run() must
   290     ///be called before using this function.
   291     const DistMap &distMap() const { return *distance;}
   292  
   293     ///Returns a reference to the shortest path tree map.
   294 
   295     ///Returns a reference to the NodeMap of the edges of the
   296     ///shortest path tree.
   297     ///\pre \ref run() must be called before using this function.
   298     const PredMap &predMap() const { return *predecessor;}
   299  
   300     ///Returns a reference to the map of nodes of shortest paths.
   301 
   302     ///Returns a reference to the NodeMap of the last but one nodes of the
   303     ///shortest path tree.
   304     ///\pre \ref run() must be called before using this function.
   305     const PredNodeMap &predNodeMap() const { return *pred_node;}
   306 
   307     ///Checks if a node is reachable from the root.
   308 
   309     ///Returns \c true if \c v is reachable from the root.
   310     ///\warning the root node is reported to be unreached!
   311     ///\todo Is this what we want?
   312     ///\pre \ref run() must be called before using this function.
   313     ///
   314     bool reached(Node v) { return G->valid((*predecessor)[v]); }
   315     
   316   };
   317   
   318 
   319   // **********************************************************************
   320   //  IMPLEMENTATIONS
   321   // **********************************************************************
   322 
   323 /// @}
   324   
   325 } //END OF NAMESPACE HUGO
   326 
   327 #endif
   328 
   329