src/work/alpar/dijkstra.h
author ladanyi
Wed, 17 Nov 2004 08:47:20 +0000
changeset 1000 7f4d07047ed8
parent 986 e997802b855c
child 1043 52a2201a88e9
permissions -rw-r--r--
Some comments and minor additions to the AdvancedController.
     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     ///\relates Dijkstra
   232     ///\ingroup flowalgs 
   233     ///\ref named-templ-param "Named parameter" for setting PredMap type
   234     template <class T>
   235     class SetPredMap : public Dijkstra< Graph,
   236 					LengthMap,
   237 					SetPredMapTraits<T> > { };
   238     
   239     template <class T>
   240     struct SetPredNodeMapTraits : public Traits {
   241       typedef T PredNodeMap;
   242       ///\todo An exception should be thrown.
   243       ///
   244       static PredNodeMap *createPredNodeMap(const Graph &G) 
   245       {
   246 	std::cerr << __FILE__ ":" << __LINE__ <<
   247 	  ": error: Special maps should be manually created" << std::endl;
   248 	exit(1);
   249       }
   250     };
   251     ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
   252 
   253     ///\ingroup flowalgs 
   254     ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
   255     template <class T>
   256     class SetPredNodeMap : public Dijkstra< Graph,
   257 					    LengthMap,
   258 					    SetPredNodeMapTraits<T> > { };
   259     
   260     template <class T>
   261     struct SetDistMapTraits : public Traits {
   262       typedef T DistMap;
   263       ///\todo An exception should be thrown.
   264       ///
   265       static DistMap *createDistMap(const Graph &G) 
   266       {
   267 	std::cerr << __FILE__ ":" << __LINE__ <<
   268 	  ": error: Special maps should be manually created" << std::endl;
   269 	exit(1);
   270       }
   271     };
   272     ///\ref named-templ-param "Named parameter" for setting DistMap type
   273 
   274     ///\ingroup flowalgs 
   275     ///\ref named-templ-param "Named parameter" for setting DistMap type
   276     template <class T>
   277     class SetDistMap : public Dijkstra< Graph,
   278 					LengthMap,
   279 					SetDistMapTraits<T> > { };
   280     
   281     ///Constructor.
   282     
   283     ///\param _G the graph the algorithm will run on.
   284     ///\param _length the length map used by the algorithm.
   285     Dijkstra(const Graph& _G, const LengthMap& _length) :
   286       G(&_G), length(&_length),
   287       predecessor(NULL), local_predecessor(false),
   288       pred_node(NULL), local_pred_node(false),
   289       distance(NULL), local_distance(false)
   290     { }
   291     
   292     ///Destructor.
   293     ~Dijkstra() 
   294     {
   295       if(local_predecessor) delete predecessor;
   296       if(local_pred_node) delete pred_node;
   297       if(local_distance) delete distance;
   298     }
   299 
   300     ///Sets the length map.
   301 
   302     ///Sets the length map.
   303     ///\return <tt> (*this) </tt>
   304     Dijkstra &setLengthMap(const LengthMap &m) 
   305     {
   306       length = &m;
   307       return *this;
   308     }
   309 
   310     ///Sets the map storing the predecessor edges.
   311 
   312     ///Sets the map storing the predecessor edges.
   313     ///If you don't use this function before calling \ref run(),
   314     ///it will allocate one. The destuctor deallocates this
   315     ///automatically allocated map, of course.
   316     ///\return <tt> (*this) </tt>
   317     Dijkstra &setPredMap(PredMap &m) 
   318     {
   319       if(local_predecessor) {
   320 	delete predecessor;
   321 	local_predecessor=false;
   322       }
   323       predecessor = &m;
   324       return *this;
   325     }
   326 
   327     ///Sets the map storing the predecessor nodes.
   328 
   329     ///Sets the map storing the predecessor nodes.
   330     ///If you don't use this function before calling \ref run(),
   331     ///it will allocate one. The destuctor deallocates this
   332     ///automatically allocated map, of course.
   333     ///\return <tt> (*this) </tt>
   334     Dijkstra &setPredNodeMap(PredNodeMap &m) 
   335     {
   336       if(local_pred_node) {
   337 	delete pred_node;
   338 	local_pred_node=false;
   339       }
   340       pred_node = &m;
   341       return *this;
   342     }
   343 
   344     ///Sets the map storing the distances calculated by the algorithm.
   345 
   346     ///Sets the map storing the distances calculated by the algorithm.
   347     ///If you don't use this function before calling \ref run(),
   348     ///it will allocate one. The destuctor deallocates this
   349     ///automatically allocated map, of course.
   350     ///\return <tt> (*this) </tt>
   351     Dijkstra &setDistMap(DistMap &m) 
   352     {
   353       if(local_distance) {
   354 	delete distance;
   355 	local_distance=false;
   356       }
   357       distance = &m;
   358       return *this;
   359     }
   360     
   361   ///Runs %Dijkstra algorithm from node \c s.
   362 
   363   ///This method runs the %Dijkstra algorithm from a root node \c s
   364   ///in order to
   365   ///compute the
   366   ///shortest path to each node. The algorithm computes
   367   ///- The shortest path tree.
   368   ///- The distance of each node from the root.
   369   ///\todo heap_map's type could also be in the traits class.
   370     void run(Node s) {
   371       
   372       init_maps();
   373       
   374       source = s;
   375       
   376       for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
   377 	predecessor->set(u,INVALID);
   378 	pred_node->set(u,INVALID);
   379       }
   380       
   381       typename Graph::template NodeMap<int> heap_map(*G,-1);
   382       
   383       Heap heap(heap_map);
   384       
   385       heap.push(s,0); 
   386       
   387       while ( !heap.empty() ) {
   388 	
   389 	Node v=heap.top(); 
   390 	Value oldvalue=heap[v];
   391 	heap.pop();
   392 	distance->set(v, oldvalue);
   393 	
   394 	
   395 	for(OutEdgeIt e(*G,v); e!=INVALID; ++e) {
   396 	  Node w=G->target(e); 
   397 	  switch(heap.state(w)) {
   398 	  case Heap::PRE_HEAP:
   399 	    heap.push(w,oldvalue+(*length)[e]); 
   400 	    predecessor->set(w,e);
   401 	    pred_node->set(w,v);
   402 	    break;
   403 	  case Heap::IN_HEAP:
   404 	    if ( oldvalue+(*length)[e] < heap[w] ) {
   405 	      heap.decrease(w, oldvalue+(*length)[e]); 
   406 	      predecessor->set(w,e);
   407 	      pred_node->set(w,v);
   408 	    }
   409 	    break;
   410 	  case Heap::POST_HEAP:
   411 	    break;
   412 	  }
   413 	}
   414       }
   415     }
   416     
   417     ///The distance of a node from the root.
   418 
   419     ///Returns the distance of a node from the root.
   420     ///\pre \ref run() must be called before using this function.
   421     ///\warning If node \c v in unreachable from the root the return value
   422     ///of this funcion is undefined.
   423     Value dist(Node v) const { return (*distance)[v]; }
   424 
   425     ///Returns the 'previous edge' of the shortest path tree.
   426 
   427     ///For a node \c v it returns the 'previous edge' of the shortest path tree,
   428     ///i.e. it returns the last edge of a shortest path from the root to \c
   429     ///v. It is \ref INVALID
   430     ///if \c v is unreachable from the root or if \c v=s. The
   431     ///shortest path tree used here is equal to the shortest path tree used in
   432     ///\ref predNode(Node v).  \pre \ref run() must be called before using
   433     ///this function.
   434     ///\todo predEdge could be a better name.
   435     Edge pred(Node v) const { return (*predecessor)[v]; }
   436 
   437     ///Returns the 'previous node' of the shortest path tree.
   438 
   439     ///For a node \c v it returns the 'previous node' of the shortest path tree,
   440     ///i.e. it returns the last but one node from a shortest path from the
   441     ///root to \c /v. It is INVALID if \c v is unreachable from the root or if
   442     ///\c v=s. The shortest path tree used here is equal to the shortest path
   443     ///tree used in \ref pred(Node v).  \pre \ref run() must be called before
   444     ///using this function.
   445     Node predNode(Node v) const { return (*pred_node)[v]; }
   446     
   447     ///Returns a reference to the NodeMap of distances.
   448 
   449     ///Returns a reference to the NodeMap of distances. \pre \ref run() must
   450     ///be called before using this function.
   451     const DistMap &distMap() const { return *distance;}
   452  
   453     ///Returns a reference to the shortest path tree map.
   454 
   455     ///Returns a reference to the NodeMap of the edges of the
   456     ///shortest path tree.
   457     ///\pre \ref run() must be called before using this function.
   458     const PredMap &predMap() const { return *predecessor;}
   459  
   460     ///Returns a reference to the map of nodes of shortest paths.
   461 
   462     ///Returns a reference to the NodeMap of the last but one nodes of the
   463     ///shortest path tree.
   464     ///\pre \ref run() must be called before using this function.
   465     const PredNodeMap &predNodeMap() const { return *pred_node;}
   466 
   467     ///Checks if a node is reachable from the root.
   468 
   469     ///Returns \c true if \c v is reachable from the root.
   470     ///\note The root node is reported to be reached!
   471     ///\pre \ref run() must be called before using this function.
   472     ///
   473     bool reached(Node v) { return v==source || (*predecessor)[v]!=INVALID; }
   474     
   475   };
   476 
   477   ///\e
   478 
   479   ///\e
   480   ///
   481   template<class TR>
   482   class _Dijkstra 
   483   {
   484     typedef TR Traits;
   485 
   486     ///The type of the underlying graph.
   487     typedef typename TR::Graph Graph;
   488     ///\e
   489     typedef typename Graph::Node Node;
   490     ///\e
   491     typedef typename Graph::NodeIt NodeIt;
   492     ///\e
   493     typedef typename Graph::Edge Edge;
   494     ///\e
   495     typedef typename Graph::OutEdgeIt OutEdgeIt;
   496     
   497     ///The type of the map that stores the edge lengths.
   498     typedef typename TR::LengthMap LengthMap;
   499     ///The type of the length of the edges.
   500     typedef typename LengthMap::Value Value;
   501     ///\brief The type of the map that stores the last
   502     ///edges of the shortest paths.
   503     typedef typename TR::PredMap PredMap;
   504     ///\brief The type of the map that stores the last but one
   505     ///nodes of the shortest paths.
   506     typedef typename TR::PredNodeMap PredNodeMap;
   507     ///The type of the map that stores the dists of the nodes.
   508     typedef typename TR::DistMap DistMap;
   509 
   510     ///The heap type used by the dijkstra algorithm.
   511     typedef typename TR::Heap Heap;
   512 
   513     /// Pointer to the underlying graph.
   514     const Graph *G;
   515     /// Pointer to the length map
   516     const LengthMap *length;
   517     ///Pointer to the map of predecessors edges.
   518     PredMap *predecessor;
   519     ///Pointer to the map of predecessors nodes.
   520     PredNodeMap *pred_node;
   521     ///Pointer to the map of distances.
   522     DistMap *distance;
   523     
   524     Node source;
   525     
   526 public:
   527     _Dijkstra() : G(0), length(0), predecessor(0), pred_node(0),
   528 		  distance(0), source(INVALID) {}
   529 
   530     _Dijkstra(const Graph &g,const LengthMap &l, Node s) :
   531       G(&g), length(&l), predecessor(0), pred_node(0),
   532 		  distance(0), source(s) {}
   533 
   534     ~_Dijkstra() 
   535     {
   536       Dijkstra<Graph,LengthMap,TR> Dij(*G,*length);
   537       if(predecessor) Dij.setPredMap(*predecessor);
   538       if(pred_node) Dij.setPredNodeMap(*pred_node);
   539       if(distance) Dij.setDistMap(*distance);
   540       Dij.run(source);
   541     }
   542 
   543     template<class T>
   544     struct SetPredMapTraits : public Traits {typedef T PredMap;};
   545     
   546     ///\e
   547     template<class T>
   548     _Dijkstra<SetPredMapTraits<T> > setPredMap(const T &t) 
   549     {
   550       _Dijkstra<SetPredMapTraits<T> > r;
   551       r.G=G;
   552       r.length=length;
   553       r.predecessor=&t;
   554       r.pred_node=pred_node;
   555       r.distance=distance;
   556       r.source=source;
   557       return r;
   558     }
   559     
   560     template<class T>
   561     struct SetPredNodeMapTraits :public Traits {typedef T PredNodeMap;};
   562     ///\e
   563     template<class T>
   564     _Dijkstra<SetPredNodeMapTraits<T> > setPredNodeMap(const T &t) 
   565     {
   566       _Dijkstra<SetPredNodeMapTraits<T> > r;
   567       r.G=G;
   568       r.length=length;
   569       r.predecessor=predecessor;
   570       r.pred_node=&t;
   571       r.distance=distance;
   572       r.source=source;
   573       return r;
   574     }
   575     
   576     template<class T>
   577     struct SetDistMapTraits : public Traits {typedef T DistMap;};
   578     ///\e
   579     template<class T>
   580     _Dijkstra<SetDistMapTraits<T> > setDistMap(const T &t) 
   581     {
   582       _Dijkstra<SetPredMapTraits<T> > r;
   583       r.G=G;
   584       r.length=length;
   585       r.predecessor=predecessor;
   586       r.pred_node=pred_node;
   587       r.distance=&t;
   588       r.source=source;
   589       return r;
   590     }
   591     
   592     ///\e
   593     _Dijkstra<TR> &setSource(Node s) 
   594     {
   595       source=s;
   596       return *this;
   597     }
   598     
   599   };
   600   
   601   ///\e
   602 
   603   ///\todo Please document...
   604   ///
   605   template<class GR, class LM>
   606   _Dijkstra<DijkstraDefaultTraits<GR,LM> >
   607   dijkstra(const GR &g,const LM &l,typename GR::Node s)
   608   {
   609     return _Dijkstra<DijkstraDefaultTraits<GR,LM> >(g,l,s);
   610   }
   611 
   612 /// @}
   613   
   614 } //END OF NAMESPACE LEMON
   615 
   616 #endif
   617 
   618