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