COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/alpar/dijkstra.h @ 953:d9c115e2eeaf

Last change on this file since 953:d9c115e2eeaf was 953:d9c115e2eeaf, checked in by Alpar Juttner, 19 years ago
  • 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.
File size: 17.1 KB
RevLine 
[906]1/* -*- C++ -*-
[921]2 * src/lemon/dijkstra.h - Part of LEMON, a generic C++ optimization library
[906]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
[921]17#ifndef LEMON_DIJKSTRA_H
18#define LEMON_DIJKSTRA_H
[255]19
[758]20///\ingroup flowalgs
[255]21///\file
22///\brief Dijkstra algorithm.
23
[953]24#include <lemon/list_graph.h>
[921]25#include <lemon/bin_heap.h>
26#include <lemon/invalid.h>
[255]27
[921]28namespace lemon {
[385]29
[758]30/// \addtogroup flowalgs
[430]31/// @{
32
[953]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 
[255]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
[880]102  ///\ref skeleton::ReadMap "ReadMap",
[255]103  ///so it is easy to change it to any kind of length.
104  ///
[880]105  ///The type of the length is determined by the
106  ///\ref skeleton::ReadMap::ValueType "ValueType" of the length map.
[255]107  ///
108  ///It is also possible to change the underlying priority heap.
109  ///
[953]110  ///\param GR The graph type the algorithm runs on. The default value is
111  ///\ref ListGraph
[584]112  ///\param LM This read-only
[385]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
[880]118  ///\ref skeleton::StaticGraph::EdgeMap "Graph::EdgeMap<int>"
[385]119  ///\param Heap The heap type used by the %Dijkstra
120  ///algorithm. The default
121  ///is using \ref BinHeap "binary heap".
[456]122  ///
[689]123  ///\author Jacint Szabo and Alpar Juttner
[693]124  ///\todo We need a typedef-names should be standardized. (-:
[734]125  ///\todo Type of \c PredMap, \c PredNodeMap and \c DistMap
126  ///should not be fixed. (Problematic to solve).
[584]127
[255]128#ifdef DOXYGEN
[584]129  template <typename GR,
130            typename LM,
[953]131            typename TR>
[255]132#else
[953]133  template <typename GR=ListGraph,
[584]134            typename LM=typename GR::template EdgeMap<int>,
[953]135            typename TR=DijkstraDefaultTraits<GR,LM> >
[255]136#endif
137  class Dijkstra{
138  public:
[953]139    typedef TR Traits;
[584]140    ///The type of the underlying graph.
141    typedef GR Graph;
[911]142    ///\e
[255]143    typedef typename Graph::Node Node;
[911]144    ///\e
[255]145    typedef typename Graph::NodeIt NodeIt;
[911]146    ///\e
[255]147    typedef typename Graph::Edge Edge;
[911]148    ///\e
[255]149    typedef typename Graph::OutEdgeIt OutEdgeIt;
150   
[584]151    ///The type of the length of the edges.
152    typedef typename LM::ValueType ValueType;
[693]153    ///The type of the map that stores the edge lengths.
[584]154    typedef LM LengthMap;
[693]155    ///\brief The type of the map that stores the last
[584]156    ///edges of the shortest paths.
[953]157    typedef typename TR::PredMap PredMap;
[693]158    ///\brief The type of the map that stores the last but one
[584]159    ///nodes of the shortest paths.
[953]160    typedef typename TR::PredNodeMap PredNodeMap;
[693]161    ///The type of the map that stores the dists of the nodes.
[953]162    typedef typename TR::DistMap DistMap;
163
164    ///The heap type used by the dijkstra algorithm.
165    typedef typename TR::Heap Heap;
[255]166
167  private:
[802]168    /// Pointer to the underlying graph.
[688]169    const Graph *G;
[802]170    /// Pointer to the length map
[688]171    const LM *length;
[802]172    ///Pointer to the map of predecessors edges.
[688]173    PredMap *predecessor;
[802]174    ///Indicates if \ref predecessor is locally allocated (\c true) or not.
[688]175    bool local_predecessor;
[802]176    ///Pointer to the map of predecessors nodes.
[688]177    PredNodeMap *pred_node;
[802]178    ///Indicates if \ref pred_node is locally allocated (\c true) or not.
[688]179    bool local_pred_node;
[802]180    ///Pointer to the map of distances.
[688]181    DistMap *distance;
[802]182    ///Indicates if \ref distance is locally allocated (\c true) or not.
[688]183    bool local_distance;
184
[802]185    ///The source node of the last execution.
[774]186    Node source;
187
[785]188    ///Initializes the maps.
[688]189   
[694]190    ///\todo Error if \c G or are \c NULL. What about \c length?
[688]191    ///\todo Better memory allocation (instead of new).
192    void init_maps()
193    {
194      if(!predecessor) {
195        local_predecessor = true;
[953]196        predecessor = Traits::createPredMap(*G);
[688]197      }
198      if(!pred_node) {
199        local_pred_node = true;
[953]200        pred_node = Traits::createPredNodeMap(*G);
[688]201      }
202      if(!distance) {
203        local_distance = true;
[953]204        distance = Traits::createDistMap(*G);
[688]205      }
206    }
[255]207   
208  public :
[953]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   
[802]264    ///Constructor.
[255]265   
[802]266    ///\param _G the graph the algorithm will run on.
267    ///\param _length the length map used by the algorithm.
[584]268    Dijkstra(const Graph& _G, const LM& _length) :
[688]269      G(&_G), length(&_length),
[707]270      predecessor(NULL), local_predecessor(false),
271      pred_node(NULL), local_pred_node(false),
272      distance(NULL), local_distance(false)
[688]273    { }
274   
[802]275    ///Destructor.
[688]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    }
[255]343   
[694]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     
[774]357      source = s;
358     
359      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
[694]360        predecessor->set(u,INVALID);
361        pred_node->set(u,INVALID);
362      }
363     
364      typename GR::template NodeMap<int> heap_map(*G,-1);
365     
[953]366      Heap heap(heap_map);
[694]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       
[774]378        for(OutEdgeIt e(*G,v); e!=INVALID; ++e) {
379          Node w=G->head(e);
[694]380          switch(heap.state(w)) {
[953]381          case Heap::PRE_HEAP:
[694]382            heap.push(w,oldvalue+(*length)[e]);
383            predecessor->set(w,e);
384            pred_node->set(w,v);
385            break;
[953]386          case Heap::IN_HEAP:
[694]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;
[953]393          case Heap::POST_HEAP:
[694]394            break;
395          }
396        }
397      }
398    }
[255]399   
[385]400    ///The distance of a node from the root.
[255]401
[385]402    ///Returns the distance of a node from the root.
[255]403    ///\pre \ref run() must be called before using this function.
[385]404    ///\warning If node \c v in unreachable from the root the return value
[255]405    ///of this funcion is undefined.
[688]406    ValueType dist(Node v) const { return (*distance)[v]; }
[373]407
[584]408    ///Returns the 'previous edge' of the shortest path tree.
[255]409
[584]410    ///For a node \c v it returns the 'previous edge' of the shortest path tree,
[785]411    ///i.e. it returns the last edge of a shortest path from the root to \c
[688]412    ///v. It is \ref INVALID
413    ///if \c v is unreachable from the root or if \c v=s. The
[385]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.
[780]417    ///\todo predEdge could be a better name.
[688]418    Edge pred(Node v) const { return (*predecessor)[v]; }
[373]419
[584]420    ///Returns the 'previous node' of the shortest path tree.
[255]421
[584]422    ///For a node \c v it returns the 'previous node' of the shortest path tree,
[385]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.
[688]428    Node predNode(Node v) const { return (*pred_node)[v]; }
[255]429   
430    ///Returns a reference to the NodeMap of distances.
431
[385]432    ///Returns a reference to the NodeMap of distances. \pre \ref run() must
433    ///be called before using this function.
[688]434    const DistMap &distMap() const { return *distance;}
[385]435 
[255]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.
[688]441    const PredMap &predMap() const { return *predecessor;}
[385]442 
443    ///Returns a reference to the map of nodes of shortest paths.
[255]444
445    ///Returns a reference to the NodeMap of the last but one nodes of the
[385]446    ///shortest path tree.
[255]447    ///\pre \ref run() must be called before using this function.
[688]448    const PredNodeMap &predNodeMap() const { return *pred_node;}
[255]449
[385]450    ///Checks if a node is reachable from the root.
[255]451
[385]452    ///Returns \c true if \c v is reachable from the root.
[802]453    ///\note The root node is reported to be reached!
[255]454    ///\pre \ref run() must be called before using this function.
[385]455    ///
[780]456    bool reached(Node v) { return v==source || (*predecessor)[v]!=INVALID; }
[255]457   
458  };
[953]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   
509public:
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  };
[255]583 
[953]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
[430]595/// @}
[255]596 
[921]597} //END OF NAMESPACE LEMON
[255]598
599#endif
600
601
Note: See TracBrowser for help on using the repository browser.