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