src/work/alpar/dijkstra.h
author alpar
Wed, 02 Feb 2005 13:11:54 +0000
changeset 1117 5767cc417f62
parent 1116 f97e1cbbd453
child 1119 d3504fc075dc
permissions -rw-r--r--
Bugfix
     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 DefPredMapTraits : 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 DefPredMap : public Dijkstra< Graph,
   235 					LengthMap,
   236 					DefPredMapTraits<T> > { };
   237     
   238     template <class T>
   239     struct DefPredNodeMapTraits : 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 DefPredNodeMap : public Dijkstra< Graph,
   256 					    LengthMap,
   257 					    DefPredNodeMapTraits<T> > { };
   258     
   259     template <class T>
   260     struct DefDistMapTraits : 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 DefDistMap : public Dijkstra< Graph,
   277 					LengthMap,
   278 					DefDistMapTraits<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 &lengthMap(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 &predMap(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 &predNodeMap(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 &distMap(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   template<class GR,class LM>
   477   class DijkstraWizardBase : public DijkstraDefaultTraits<GR,LM>
   478   {
   479 
   480     typedef DijkstraDefaultTraits<GR,LM> Base;
   481   protected:
   482     /// Pointer to the underlying graph.
   483     void *_g;
   484     /// Pointer to the length map
   485     void *_length;
   486     ///Pointer to the map of predecessors edges.
   487     void *_pred;
   488     ///Pointer to the map of predecessors nodes.
   489     void *_predNode;
   490     ///Pointer to the map of distances.
   491     void *_dist;
   492     ///Pointer to the source node.
   493     void *_source;
   494 
   495     typedef typename Base::Graph::Node Node;
   496 
   497     public:
   498     DijkstraWizardBase() : _g(0), _length(0), _pred(0), _predNode(0),
   499 		       _dist(0), _source(INVALID) {}
   500 
   501     DijkstraWizardBase(const GR &g,const LM &l, Node s=INVALID) :
   502       _g((void *)&g), _length((void *)&l), _pred(0), _predNode(0),
   503 		  _dist(0), _source((void *)&s) {}
   504 
   505   };
   506   
   507   ///\e
   508 
   509   ///\e
   510   ///
   511   template<class TR>
   512   class DijkstraWizard : public TR
   513   {
   514     typedef TR Base;
   515 
   516     ///The type of the underlying graph.
   517     typedef typename TR::Graph Graph;
   518     ///\e
   519     typedef typename Graph::Node Node;
   520     ///\e
   521     typedef typename Graph::NodeIt NodeIt;
   522     ///\e
   523     typedef typename Graph::Edge Edge;
   524     ///\e
   525     typedef typename Graph::OutEdgeIt OutEdgeIt;
   526     
   527     ///The type of the map that stores the edge lengths.
   528     typedef typename TR::LengthMap LengthMap;
   529     ///The type of the length of the edges.
   530     typedef typename LengthMap::Value Value;
   531     ///\brief The type of the map that stores the last
   532     ///edges of the shortest paths.
   533     typedef typename TR::PredMap PredMap;
   534     ///\brief The type of the map that stores the last but one
   535     ///nodes of the shortest paths.
   536     typedef typename TR::PredNodeMap PredNodeMap;
   537     ///The type of the map that stores the dists of the nodes.
   538     typedef typename TR::DistMap DistMap;
   539 
   540     ///The heap type used by the dijkstra algorithm.
   541     typedef typename TR::Heap Heap;
   542 public:
   543     DijkstraWizard() : TR() {}
   544 
   545     DijkstraWizard(const Graph &g,const LengthMap &l, Node s=INVALID) :
   546       TR(g,l,s) {}
   547 
   548     DijkstraWizard(const TR &b) : TR(b) {}
   549 
   550     ~DijkstraWizard() {}
   551 
   552     ///\e
   553     void run()
   554     {
   555       Dijkstra<Graph,LengthMap,TR> Dij(*(Graph*)_g,*(LengthMap*)_length);
   556       if(_pred) Dij.predMap(*(PredMap*)_pred);
   557       if(_predNode) Dij.predNodeMap(*(PredNodeMap*)_predNode);
   558       if(_dist) Dij.distMap(*(DistMap*)_dist);
   559       Dij.run(*(Node*)_source);
   560     }
   561 
   562     ///\e
   563     void run(Node s)
   564     {
   565       _source=(void *)&s;
   566       run();
   567     }
   568 
   569     template<class T>
   570     struct DefPredMapBase : public Base {
   571       typedef T PredMap;
   572       static PredMap *createPredMap(const Graph &G) { return 0; };
   573       DefPredMapBase(const Base &b) : Base(b) {}
   574     };
   575     
   576     ///\e
   577     template<class T>
   578     DijkstraWizard<DefPredMapBase<T> > predMap(const T &t) 
   579     {
   580       _pred=(void *)&t;
   581       return DijkstraWizard<DefPredMapBase<T> >(*this);
   582     }
   583     
   584 
   585     template<class T>
   586     struct DefPredNodeMapBase : public Base {
   587       typedef T PredNodeMap;
   588       static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
   589       DefPredNodeMapBase(const Base &b) : Base(b) {}
   590     };
   591     
   592     ///\e
   593     template<class T>
   594     DijkstraWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t) 
   595     {
   596       _predNode=(void *)&t;
   597       return DijkstraWizard<DefPredNodeMapBase<T> >(*this);
   598     }
   599    
   600     template<class T>
   601     struct DefDistMapBase : public Base {
   602       typedef T DistMap;
   603       static DistMap *createDistMap(const Graph &G) { return 0; };
   604       DefDistMapBase(const Base &b) : Base(b) {}
   605     };
   606     
   607     ///\e
   608     template<class T>
   609     DijkstraWizard<DefDistMapBase<T> > distMap(const T &t) 
   610     {
   611       _dist=(void *)&t;
   612       return DijkstraWizard<DefDistMapBase<T> >(*this);
   613     }
   614     
   615     ///\e
   616     DijkstraWizard<TR> &source(Node s) 
   617     {
   618       source=(void *)&s;
   619       return *this;
   620     }
   621     
   622   };
   623   
   624   ///\e
   625 
   626   ///\todo Please document...
   627   ///
   628   template<class GR, class LM>
   629   DijkstraWizard<DijkstraWizardBase<GR,LM> >
   630   dijkstra(const GR &g,const LM &l,typename GR::Node s=INVALID)
   631   {
   632     return DijkstraWizard<DijkstraWizardBase<GR,LM> >(g,l,s);
   633   }
   634 
   635 /// @}
   636   
   637 } //END OF NAMESPACE LEMON
   638 
   639 #endif
   640