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