src/work/alpar/dijkstra.h
author alpar
Fri, 28 Jan 2005 08:53:48 +0000
changeset 1101 9286569c3749
parent 987 87f7c54892df
child 1116 f97e1cbbd453
permissions -rw-r--r--
Wrap a long line
     1 /* -*- C++ -*-
     2  * src/lemon/dijkstra.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Combinatorial Optimization Research Group, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_DIJKSTRA_H
    18 #define LEMON_DIJKSTRA_H
    19 
    20 ///\ingroup flowalgs
    21 ///\file
    22 ///\brief Dijkstra algorithm.
    23 
    24 #include <lemon/list_graph.h>
    25 #include <lemon/bin_heap.h>
    26 #include <lemon/invalid.h>
    27 
    28 namespace lemon {
    29 
    30 /// \addtogroup flowalgs
    31 /// @{
    32 
    33   ///Default traits class of Dijkstra class.
    34 
    35   ///Default traits class of Dijkstra class.
    36   ///\param GR Graph type.
    37   ///\param LM Type of length map.
    38   template<class GR, class LM>
    39   struct DijkstraDefaultTraits
    40   {
    41     ///The graph type the algorithm runs on. 
    42     typedef GR Graph;
    43     ///The type of the map that stores the edge lengths.
    44 
    45     ///It must meet the \ref concept::ReadMap "ReadMap" concept.
    46     ///
    47     typedef LM LengthMap;
    48     //The type of the length of the edges.
    49     typedef typename LM::Value Value;
    50     ///The heap type used by Dijkstra algorithm.
    51 
    52     ///The heap type used by Dijkstra algorithm.
    53     ///
    54     ///\sa BinHeap
    55     ///\sa Dijkstra
    56     typedef BinHeap<typename Graph::Node,
    57 		    typename LM::Value,
    58 		    typename GR::template NodeMap<int>,
    59 		    std::less<Value> > Heap;
    60 
    61     ///\brief The type of the map that stores the last
    62     ///edges of the shortest paths.
    63     /// 
    64     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
    65     ///
    66     typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
    67     ///Instantiates a PredMap.
    68  
    69     ///\todo Please document...
    70     ///
    71     static PredMap *createPredMap(const GR &G) 
    72     {
    73       return new PredMap(G);
    74     }
    75     ///\brief The type of the map that stores the last but one
    76     ///nodes of the shortest paths.
    77     ///
    78     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
    79     ///
    80     typedef typename Graph::template NodeMap<typename GR::Node> PredNodeMap;
    81     ///Instantiates a PredNodeMap.
    82  
    83     ///\todo Please document...
    84     ///
    85     static PredNodeMap *createPredNodeMap(const GR &G)
    86     {
    87       return new PredNodeMap(G);
    88     }
    89     ///The type of the map that stores the dists of the nodes.
    90  
    91     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
    92     ///
    93     typedef typename Graph::template NodeMap<typename LM::Value> DistMap;
    94     ///Instantiates a DistMap.
    95  
    96     ///\todo Please document...
    97     ///
    98     static DistMap *createDistMap(const GR &G)
    99     {
   100       return new DistMap(G);
   101     }
   102   };
   103   
   104   ///%Dijkstra algorithm class.
   105 
   106   ///This class provides an efficient implementation of %Dijkstra algorithm.
   107   ///The edge lengths are passed to the algorithm using a
   108   ///\ref concept::ReadMap "ReadMap",
   109   ///so it is easy to change it to any kind of length.
   110   ///
   111   ///The type of the length is determined by the
   112   ///\ref concept::ReadMap::Value "Value" of the length map.
   113   ///
   114   ///It is also possible to change the underlying priority heap.
   115   ///
   116   ///\param GR The graph type the algorithm runs on. The default value is
   117   ///\ref ListGraph. The value of GR is not used directly by Dijkstra, it
   118   ///is only passed to \ref DijkstraDefaultTraits.
   119   ///\param LM This read-only
   120   ///EdgeMap
   121   ///determines the
   122   ///lengths of the edges. It is read once for each edge, so the map
   123   ///may involve in relatively time consuming process to compute the edge
   124   ///length if it is necessary. The default map type is
   125   ///\ref concept::StaticGraph::EdgeMap "Graph::EdgeMap<int>".
   126   ///The value of LM is not used directly by Dijkstra, it
   127   ///is only passed to \ref DijkstraDefaultTraits.
   128   ///\param TR Traits class to set various data types used by the algorithm.
   129   ///The default traits class is
   130   ///\ref DijkstraDefaultTraits "DijkstraDefaultTraits<GR,LM>".
   131   ///See \ref DijkstraDefaultTraits for the documentation of
   132   ///a Dijkstra traits class.
   133   ///
   134   ///\author Jacint Szabo and Alpar Juttner
   135   ///\todo We need a typedef-names should be standardized. (-:
   136 
   137 #ifdef DOXYGEN
   138   template <typename GR,
   139 	    typename LM,
   140 	    typename TR>
   141 #else
   142   template <typename GR=ListGraph,
   143 	    typename LM=typename GR::template EdgeMap<int>,
   144 	    typename TR=DijkstraDefaultTraits<GR,LM> >
   145 #endif
   146   class Dijkstra{
   147   public:
   148     typedef TR Traits;
   149     ///The type of the underlying graph.
   150     typedef typename TR::Graph Graph;
   151     ///\e
   152     typedef typename Graph::Node Node;
   153     ///\e
   154     typedef typename Graph::NodeIt NodeIt;
   155     ///\e
   156     typedef typename Graph::Edge Edge;
   157     ///\e
   158     typedef typename Graph::OutEdgeIt OutEdgeIt;
   159     
   160     ///The type of the length of the edges.
   161     typedef typename TR::LengthMap::Value Value;
   162     ///The type of the map that stores the edge lengths.
   163     typedef typename TR::LengthMap LengthMap;
   164     ///\brief The type of the map that stores the last
   165     ///edges of the shortest paths.
   166     typedef typename TR::PredMap PredMap;
   167     ///\brief The type of the map that stores the last but one
   168     ///nodes of the shortest paths.
   169     typedef typename TR::PredNodeMap PredNodeMap;
   170     ///The type of the map that stores the dists of the nodes.
   171     typedef typename TR::DistMap DistMap;
   172     ///The heap type used by the dijkstra algorithm.
   173     typedef typename TR::Heap Heap;
   174   private:
   175     /// Pointer to the underlying graph.
   176     const Graph *G;
   177     /// Pointer to the length map
   178     const LengthMap *length;
   179     ///Pointer to the map of predecessors edges.
   180     PredMap *predecessor;
   181     ///Indicates if \ref predecessor is locally allocated (\c true) or not.
   182     bool local_predecessor;
   183     ///Pointer to the map of predecessors nodes.
   184     PredNodeMap *pred_node;
   185     ///Indicates if \ref pred_node is locally allocated (\c true) or not.
   186     bool local_pred_node;
   187     ///Pointer to the map of distances.
   188     DistMap *distance;
   189     ///Indicates if \ref distance is locally allocated (\c true) or not.
   190     bool local_distance;
   191 
   192     ///The source node of the last execution.
   193     Node source;
   194 
   195     ///Initializes the maps.
   196     
   197     ///\todo Error if \c G or are \c NULL. What about \c length?
   198     ///\todo Better memory allocation (instead of new).
   199     void init_maps() 
   200     {
   201       if(!predecessor) {
   202 	local_predecessor = true;
   203 	predecessor = Traits::createPredMap(*G);
   204       }
   205       if(!pred_node) {
   206 	local_pred_node = true;
   207 	pred_node = Traits::createPredNodeMap(*G);
   208       }
   209       if(!distance) {
   210 	local_distance = true;
   211 	distance = Traits::createDistMap(*G);
   212       }
   213     }
   214     
   215   public :
   216 
   217     template <class T>
   218     struct SetPredMapTraits : public Traits {
   219       typedef T PredMap;
   220       ///\todo An exception should be thrown.
   221       ///
   222       static PredMap *createPredMap(const Graph &G) 
   223       {
   224 	std::cerr << __FILE__ ":" << __LINE__ <<
   225 	  ": error: Special maps should be manually created" << std::endl;
   226 	exit(1);
   227       }
   228     };
   229     ///\ref named-templ-param "Named parameter" for setting PredMap type
   230 
   231     ///\ref named-templ-param "Named parameter" for setting PredMap type
   232     ///
   233     template <class T>
   234     class SetPredMap : public Dijkstra< Graph,
   235 					LengthMap,
   236 					SetPredMapTraits<T> > { };
   237     
   238     template <class T>
   239     struct SetPredNodeMapTraits : public Traits {
   240       typedef T PredNodeMap;
   241       ///\todo An exception should be thrown.
   242       ///
   243       static PredNodeMap *createPredNodeMap(const Graph &G) 
   244       {
   245 	std::cerr << __FILE__ ":" << __LINE__ <<
   246 	  ": error: Special maps should be manually created" << std::endl;
   247 	exit(1);
   248       }
   249     };
   250     ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
   251 
   252     ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
   253     ///
   254     template <class T>
   255     class SetPredNodeMap : public Dijkstra< Graph,
   256 					    LengthMap,
   257 					    SetPredNodeMapTraits<T> > { };
   258     
   259     template <class T>
   260     struct SetDistMapTraits : public Traits {
   261       typedef T DistMap;
   262       ///\todo An exception should be thrown.
   263       ///
   264       static DistMap *createDistMap(const Graph &G) 
   265       {
   266 	std::cerr << __FILE__ ":" << __LINE__ <<
   267 	  ": error: Special maps should be manually created" << std::endl;
   268 	exit(1);
   269       }
   270     };
   271     ///\ref named-templ-param "Named parameter" for setting DistMap type
   272 
   273     ///\ref named-templ-param "Named parameter" for setting DistMap type
   274     ///
   275     template <class T>
   276     class SetDistMap : public Dijkstra< Graph,
   277 					LengthMap,
   278 					SetDistMapTraits<T> > { };
   279     
   280     ///Constructor.
   281     
   282     ///\param _G the graph the algorithm will run on.
   283     ///\param _length the length map used by the algorithm.
   284     Dijkstra(const Graph& _G, const LengthMap& _length) :
   285       G(&_G), length(&_length),
   286       predecessor(NULL), local_predecessor(false),
   287       pred_node(NULL), local_pred_node(false),
   288       distance(NULL), local_distance(false)
   289     { }
   290     
   291     ///Destructor.
   292     ~Dijkstra() 
   293     {
   294       if(local_predecessor) delete predecessor;
   295       if(local_pred_node) delete pred_node;
   296       if(local_distance) delete distance;
   297     }
   298 
   299     ///Sets the length map.
   300 
   301     ///Sets the length map.
   302     ///\return <tt> (*this) </tt>
   303     Dijkstra &setLengthMap(const LengthMap &m) 
   304     {
   305       length = &m;
   306       return *this;
   307     }
   308 
   309     ///Sets the map storing the predecessor edges.
   310 
   311     ///Sets the map storing the predecessor edges.
   312     ///If you don't use this function before calling \ref run(),
   313     ///it will allocate one. The destuctor deallocates this
   314     ///automatically allocated map, of course.
   315     ///\return <tt> (*this) </tt>
   316     Dijkstra &setPredMap(PredMap &m) 
   317     {
   318       if(local_predecessor) {
   319 	delete predecessor;
   320 	local_predecessor=false;
   321       }
   322       predecessor = &m;
   323       return *this;
   324     }
   325 
   326     ///Sets the map storing the predecessor nodes.
   327 
   328     ///Sets the map storing the predecessor nodes.
   329     ///If you don't use this function before calling \ref run(),
   330     ///it will allocate one. The destuctor deallocates this
   331     ///automatically allocated map, of course.
   332     ///\return <tt> (*this) </tt>
   333     Dijkstra &setPredNodeMap(PredNodeMap &m) 
   334     {
   335       if(local_pred_node) {
   336 	delete pred_node;
   337 	local_pred_node=false;
   338       }
   339       pred_node = &m;
   340       return *this;
   341     }
   342 
   343     ///Sets the map storing the distances calculated by the algorithm.
   344 
   345     ///Sets the map storing the distances calculated by the algorithm.
   346     ///If you don't use this function before calling \ref run(),
   347     ///it will allocate one. The destuctor deallocates this
   348     ///automatically allocated map, of course.
   349     ///\return <tt> (*this) </tt>
   350     Dijkstra &setDistMap(DistMap &m) 
   351     {
   352       if(local_distance) {
   353 	delete distance;
   354 	local_distance=false;
   355       }
   356       distance = &m;
   357       return *this;
   358     }
   359     
   360   ///Runs %Dijkstra algorithm from node \c s.
   361 
   362   ///This method runs the %Dijkstra algorithm from a root node \c s
   363   ///in order to
   364   ///compute the
   365   ///shortest path to each node. The algorithm computes
   366   ///- The shortest path tree.
   367   ///- The distance of each node from the root.
   368   ///\todo heap_map's type could also be in the traits class.
   369     void run(Node s) {
   370       
   371       init_maps();
   372       
   373       source = s;
   374       
   375       for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
   376 	predecessor->set(u,INVALID);
   377 	pred_node->set(u,INVALID);
   378       }
   379       
   380       typename Graph::template NodeMap<int> heap_map(*G,-1);
   381       
   382       Heap heap(heap_map);
   383       
   384       heap.push(s,0); 
   385       
   386       while ( !heap.empty() ) {
   387 	
   388 	Node v=heap.top(); 
   389 	Value oldvalue=heap[v];
   390 	heap.pop();
   391 	distance->set(v, oldvalue);
   392 	
   393 	
   394 	for(OutEdgeIt e(*G,v); e!=INVALID; ++e) {
   395 	  Node w=G->target(e); 
   396 	  switch(heap.state(w)) {
   397 	  case Heap::PRE_HEAP:
   398 	    heap.push(w,oldvalue+(*length)[e]); 
   399 	    predecessor->set(w,e);
   400 	    pred_node->set(w,v);
   401 	    break;
   402 	  case Heap::IN_HEAP:
   403 	    if ( oldvalue+(*length)[e] < heap[w] ) {
   404 	      heap.decrease(w, oldvalue+(*length)[e]); 
   405 	      predecessor->set(w,e);
   406 	      pred_node->set(w,v);
   407 	    }
   408 	    break;
   409 	  case Heap::POST_HEAP:
   410 	    break;
   411 	  }
   412 	}
   413       }
   414     }
   415     
   416     ///The distance of a node from the root.
   417 
   418     ///Returns the distance of a node from the root.
   419     ///\pre \ref run() must be called before using this function.
   420     ///\warning If node \c v in unreachable from the root the return value
   421     ///of this funcion is undefined.
   422     Value dist(Node v) const { return (*distance)[v]; }
   423 
   424     ///Returns the 'previous edge' of the shortest path tree.
   425 
   426     ///For a node \c v it returns the 'previous edge' of the shortest path tree,
   427     ///i.e. it returns the last edge of a shortest path from the root to \c
   428     ///v. It is \ref INVALID
   429     ///if \c v is unreachable from the root or if \c v=s. The
   430     ///shortest path tree used here is equal to the shortest path tree used in
   431     ///\ref predNode(Node v).  \pre \ref run() must be called before using
   432     ///this function.
   433     ///\todo predEdge could be a better name.
   434     Edge pred(Node v) const { return (*predecessor)[v]; }
   435 
   436     ///Returns the 'previous node' of the shortest path tree.
   437 
   438     ///For a node \c v it returns the 'previous node' of the shortest path tree,
   439     ///i.e. it returns the last but one node from a shortest path from the
   440     ///root to \c /v. It is INVALID if \c v is unreachable from the root or if
   441     ///\c v=s. The shortest path tree used here is equal to the shortest path
   442     ///tree used in \ref pred(Node v).  \pre \ref run() must be called before
   443     ///using this function.
   444     Node predNode(Node v) const { return (*pred_node)[v]; }
   445     
   446     ///Returns a reference to the NodeMap of distances.
   447 
   448     ///Returns a reference to the NodeMap of distances. \pre \ref run() must
   449     ///be called before using this function.
   450     const DistMap &distMap() const { return *distance;}
   451  
   452     ///Returns a reference to the shortest path tree map.
   453 
   454     ///Returns a reference to the NodeMap of the edges of the
   455     ///shortest path tree.
   456     ///\pre \ref run() must be called before using this function.
   457     const PredMap &predMap() const { return *predecessor;}
   458  
   459     ///Returns a reference to the map of nodes of shortest paths.
   460 
   461     ///Returns a reference to the NodeMap of the last but one nodes of the
   462     ///shortest path tree.
   463     ///\pre \ref run() must be called before using this function.
   464     const PredNodeMap &predNodeMap() const { return *pred_node;}
   465 
   466     ///Checks if a node is reachable from the root.
   467 
   468     ///Returns \c true if \c v is reachable from the root.
   469     ///\note The root node is reported to be reached!
   470     ///\pre \ref run() must be called before using this function.
   471     ///
   472     bool reached(Node v) { return v==source || (*predecessor)[v]!=INVALID; }
   473     
   474   };
   475 
   476   ///\e
   477 
   478   ///\e
   479   ///
   480   template<class TR>
   481   class _Dijkstra 
   482   {
   483     typedef TR Traits;
   484 
   485     ///The type of the underlying graph.
   486     typedef typename TR::Graph Graph;
   487     ///\e
   488     typedef typename Graph::Node Node;
   489     ///\e
   490     typedef typename Graph::NodeIt NodeIt;
   491     ///\e
   492     typedef typename Graph::Edge Edge;
   493     ///\e
   494     typedef typename Graph::OutEdgeIt OutEdgeIt;
   495     
   496     ///The type of the map that stores the edge lengths.
   497     typedef typename TR::LengthMap LengthMap;
   498     ///The type of the length of the edges.
   499     typedef typename LengthMap::Value Value;
   500     ///\brief The type of the map that stores the last
   501     ///edges of the shortest paths.
   502     typedef typename TR::PredMap PredMap;
   503     ///\brief The type of the map that stores the last but one
   504     ///nodes of the shortest paths.
   505     typedef typename TR::PredNodeMap PredNodeMap;
   506     ///The type of the map that stores the dists of the nodes.
   507     typedef typename TR::DistMap DistMap;
   508 
   509     ///The heap type used by the dijkstra algorithm.
   510     typedef typename TR::Heap Heap;
   511 
   512     /// Pointer to the underlying graph.
   513     const Graph *G;
   514     /// Pointer to the length map
   515     const LengthMap *length;
   516     ///Pointer to the map of predecessors edges.
   517     PredMap *predecessor;
   518     ///Pointer to the map of predecessors nodes.
   519     PredNodeMap *pred_node;
   520     ///Pointer to the map of distances.
   521     DistMap *distance;
   522     
   523     Node source;
   524     
   525 public:
   526     _Dijkstra() : G(0), length(0), predecessor(0), pred_node(0),
   527 		  distance(0), source(INVALID) {}
   528 
   529     _Dijkstra(const Graph &g,const LengthMap &l, Node s) :
   530       G(&g), length(&l), predecessor(0), pred_node(0),
   531 		  distance(0), source(s) {}
   532 
   533     ~_Dijkstra() 
   534     {
   535       Dijkstra<Graph,LengthMap,TR> Dij(*G,*length);
   536       if(predecessor) Dij.setPredMap(*predecessor);
   537       if(pred_node) Dij.setPredNodeMap(*pred_node);
   538       if(distance) Dij.setDistMap(*distance);
   539       Dij.run(source);
   540     }
   541 
   542     template<class T>
   543     struct SetPredMapTraits : public Traits {typedef T PredMap;};
   544     
   545     ///\e
   546     template<class T>
   547     _Dijkstra<SetPredMapTraits<T> > setPredMap(const T &t) 
   548     {
   549       _Dijkstra<SetPredMapTraits<T> > r;
   550       r.G=G;
   551       r.length=length;
   552       r.predecessor=&t;
   553       r.pred_node=pred_node;
   554       r.distance=distance;
   555       r.source=source;
   556       return r;
   557     }
   558     
   559     template<class T>
   560     struct SetPredNodeMapTraits :public Traits {typedef T PredNodeMap;};
   561     ///\e
   562     template<class T>
   563     _Dijkstra<SetPredNodeMapTraits<T> > setPredNodeMap(const T &t) 
   564     {
   565       _Dijkstra<SetPredNodeMapTraits<T> > r;
   566       r.G=G;
   567       r.length=length;
   568       r.predecessor=predecessor;
   569       r.pred_node=&t;
   570       r.distance=distance;
   571       r.source=source;
   572       return r;
   573     }
   574     
   575     template<class T>
   576     struct SetDistMapTraits : public Traits {typedef T DistMap;};
   577     ///\e
   578     template<class T>
   579     _Dijkstra<SetDistMapTraits<T> > setDistMap(const T &t) 
   580     {
   581       _Dijkstra<SetPredMapTraits<T> > r;
   582       r.G=G;
   583       r.length=length;
   584       r.predecessor=predecessor;
   585       r.pred_node=pred_node;
   586       r.distance=&t;
   587       r.source=source;
   588       return r;
   589     }
   590     
   591     ///\e
   592     _Dijkstra<TR> &setSource(Node s) 
   593     {
   594       source=s;
   595       return *this;
   596     }
   597     
   598   };
   599   
   600   ///\e
   601 
   602   ///\todo Please document...
   603   ///
   604   template<class GR, class LM>
   605   _Dijkstra<DijkstraDefaultTraits<GR,LM> >
   606   dijkstra(const GR &g,const LM &l,typename GR::Node s)
   607   {
   608     return _Dijkstra<DijkstraDefaultTraits<GR,LM> >(g,l,s);
   609   }
   610 
   611 /// @}
   612   
   613 } //END OF NAMESPACE LEMON
   614 
   615 #endif
   616 
   617