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