src/work/deba/dijkstra.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000
changeset 822 88226d9fe821
parent 694 2d87cefb35b2
child 880 9d0bfd35b97c
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

Some macros and comments has been changed.
alpar@255
     1
// -*- C++ -*-
alpar@255
     2
#ifndef HUGO_DIJKSTRA_H
alpar@255
     3
#define HUGO_DIJKSTRA_H
alpar@255
     4
klao@491
     5
///\ingroup galgs
alpar@255
     6
///\file
alpar@255
     7
///\brief Dijkstra algorithm.
alpar@255
     8
ladanyi@542
     9
#include <hugo/bin_heap.h>
ladanyi@542
    10
#include <hugo/invalid.h>
alpar@255
    11
alpar@255
    12
namespace hugo {
jacint@385
    13
alpar@430
    14
/// \addtogroup galgs
alpar@430
    15
/// @{
alpar@430
    16
alpar@255
    17
  ///%Dijkstra algorithm class.
alpar@255
    18
alpar@255
    19
  ///This class provides an efficient implementation of %Dijkstra algorithm.
alpar@255
    20
  ///The edge lengths are passed to the algorithm using a
alpar@255
    21
  ///\ref ReadMapSkeleton "readable map",
alpar@255
    22
  ///so it is easy to change it to any kind of length.
alpar@255
    23
  ///
alpar@255
    24
  ///The type of the length is determined by the \c ValueType of the length map.
alpar@255
    25
  ///
alpar@255
    26
  ///It is also possible to change the underlying priority heap.
alpar@255
    27
  ///
alpar@584
    28
  ///\param GR The graph type the algorithm runs on.
alpar@584
    29
  ///\param LM This read-only
jacint@385
    30
  ///EdgeMap
jacint@385
    31
  ///determines the
jacint@385
    32
  ///lengths of the edges. It is read once for each edge, so the map
jacint@385
    33
  ///may involve in relatively time consuming process to compute the edge
jacint@385
    34
  ///length if it is necessary. The default map type is
jacint@385
    35
  ///\ref GraphSkeleton::EdgeMap "Graph::EdgeMap<int>"
jacint@385
    36
  ///\param Heap The heap type used by the %Dijkstra
jacint@385
    37
  ///algorithm. The default
jacint@385
    38
  ///is using \ref BinHeap "binary heap".
alpar@456
    39
  ///
alpar@689
    40
  ///\author Jacint Szabo and Alpar Juttner
alpar@693
    41
  ///\todo We need a typedef-names should be standardized. (-:
alpar@584
    42
alpar@255
    43
#ifdef DOXYGEN
alpar@584
    44
  template <typename GR,
alpar@584
    45
	    typename LM,
alpar@255
    46
	    typename Heap>
alpar@255
    47
#else
alpar@584
    48
  template <typename GR,
alpar@584
    49
	    typename LM=typename GR::template EdgeMap<int>,
alpar@532
    50
	    template <class,class,class,class> class Heap = BinHeap >
alpar@255
    51
#endif
alpar@255
    52
  class Dijkstra{
alpar@255
    53
  public:
alpar@584
    54
    ///The type of the underlying graph.
alpar@584
    55
    typedef GR Graph;
alpar@255
    56
    typedef typename Graph::Node Node;
alpar@255
    57
    typedef typename Graph::NodeIt NodeIt;
alpar@255
    58
    typedef typename Graph::Edge Edge;
alpar@255
    59
    typedef typename Graph::OutEdgeIt OutEdgeIt;
alpar@255
    60
    
alpar@584
    61
    ///The type of the length of the edges.
alpar@584
    62
    typedef typename LM::ValueType ValueType;
alpar@693
    63
    ///The type of the map that stores the edge lengths.
alpar@584
    64
    typedef LM LengthMap;
alpar@693
    65
    ///\brief The type of the map that stores the last
alpar@584
    66
    ///edges of the shortest paths.
marci@433
    67
    typedef typename Graph::template NodeMap<Edge> PredMap;
alpar@693
    68
    ///\brief The type of the map that stores the last but one
alpar@584
    69
    ///nodes of the shortest paths.
marci@433
    70
    typedef typename Graph::template NodeMap<Node> PredNodeMap;
alpar@693
    71
    ///The type of the map that stores the dists of the nodes.
marci@433
    72
    typedef typename Graph::template NodeMap<ValueType> DistMap;
alpar@255
    73
alpar@255
    74
  private:
alpar@688
    75
    const Graph *G;
alpar@688
    76
    const LM *length;
alpar@688
    77
    //    bool local_length;
alpar@688
    78
    PredMap *predecessor;
alpar@688
    79
    bool local_predecessor;
alpar@688
    80
    PredNodeMap *pred_node;
alpar@688
    81
    bool local_pred_node;
alpar@688
    82
    DistMap *distance;
alpar@688
    83
    bool local_distance;
alpar@688
    84
alpar@688
    85
    ///Initialize maps
alpar@688
    86
    
alpar@694
    87
    ///\todo Error if \c G or are \c NULL. What about \c length?
alpar@688
    88
    ///\todo Better memory allocation (instead of new).
alpar@688
    89
    void init_maps() 
alpar@688
    90
    {
alpar@688
    91
//       if(!length) {
alpar@688
    92
// 	local_length = true;
alpar@688
    93
// 	length = new LM(G);
alpar@688
    94
//       }
alpar@688
    95
      if(!predecessor) {
alpar@688
    96
	local_predecessor = true;
alpar@688
    97
	predecessor = new PredMap(*G);
alpar@688
    98
      }
alpar@688
    99
      if(!pred_node) {
alpar@688
   100
	local_pred_node = true;
alpar@688
   101
	pred_node = new PredNodeMap(*G);
alpar@688
   102
      }
alpar@688
   103
      if(!distance) {
alpar@688
   104
	local_distance = true;
alpar@688
   105
	distance = new DistMap(*G);
alpar@688
   106
      }
alpar@688
   107
    }
alpar@255
   108
    
alpar@255
   109
  public :
alpar@255
   110
    
alpar@584
   111
    Dijkstra(const Graph& _G, const LM& _length) :
alpar@688
   112
      G(&_G), length(&_length),
alpar@688
   113
      predecessor(NULL), pred_node(NULL), distance(NULL),
alpar@688
   114
      local_predecessor(false), local_pred_node(false), local_distance(false)
alpar@688
   115
    { }
alpar@688
   116
    
alpar@688
   117
    ~Dijkstra() 
alpar@688
   118
    {
alpar@688
   119
      //      if(local_length) delete length;
alpar@688
   120
      if(local_predecessor) delete predecessor;
alpar@688
   121
      if(local_pred_node) delete pred_node;
alpar@688
   122
      if(local_distance) delete distance;
alpar@688
   123
    }
alpar@688
   124
alpar@688
   125
    ///Sets the graph the algorithm will run on.
alpar@688
   126
alpar@688
   127
    ///Sets the graph the algorithm will run on.
alpar@688
   128
    ///\return <tt> (*this) </tt>
alpar@688
   129
    Dijkstra &setGraph(const Graph &_G) 
alpar@688
   130
    {
alpar@688
   131
      G = &_G;
alpar@688
   132
      return *this;
alpar@688
   133
    }
alpar@688
   134
    ///Sets the length map.
alpar@688
   135
alpar@688
   136
    ///Sets the length map.
alpar@688
   137
    ///\return <tt> (*this) </tt>
alpar@688
   138
    Dijkstra &setLengthMap(const LM &m) 
alpar@688
   139
    {
alpar@688
   140
//       if(local_length) {
alpar@688
   141
// 	delete length;
alpar@688
   142
// 	local_length=false;
alpar@688
   143
//       }
alpar@688
   144
      length = &m;
alpar@688
   145
      return *this;
alpar@688
   146
    }
alpar@688
   147
alpar@688
   148
    ///Sets the map storing the predecessor edges.
alpar@688
   149
alpar@688
   150
    ///Sets the map storing the predecessor edges.
alpar@688
   151
    ///If you don't use this function before calling \ref run(),
alpar@688
   152
    ///it will allocate one. The destuctor deallocates this
alpar@688
   153
    ///automatically allocated map, of course.
alpar@688
   154
    ///\return <tt> (*this) </tt>
alpar@688
   155
    Dijkstra &setPredMap(PredMap &m) 
alpar@688
   156
    {
alpar@688
   157
      if(local_predecessor) {
alpar@688
   158
	delete predecessor;
alpar@688
   159
	local_predecessor=false;
alpar@688
   160
      }
alpar@688
   161
      predecessor = &m;
alpar@688
   162
      return *this;
alpar@688
   163
    }
alpar@688
   164
alpar@688
   165
    ///Sets the map storing the predecessor nodes.
alpar@688
   166
alpar@688
   167
    ///Sets the map storing the predecessor nodes.
alpar@688
   168
    ///If you don't use this function before calling \ref run(),
alpar@688
   169
    ///it will allocate one. The destuctor deallocates this
alpar@688
   170
    ///automatically allocated map, of course.
alpar@688
   171
    ///\return <tt> (*this) </tt>
alpar@688
   172
    Dijkstra &setPredNodeMap(PredNodeMap &m) 
alpar@688
   173
    {
alpar@688
   174
      if(local_pred_node) {
alpar@688
   175
	delete pred_node;
alpar@688
   176
	local_pred_node=false;
alpar@688
   177
      }
alpar@688
   178
      pred_node = &m;
alpar@688
   179
      return *this;
alpar@688
   180
    }
alpar@688
   181
alpar@688
   182
    ///Sets the map storing the distances calculated by the algorithm.
alpar@688
   183
alpar@688
   184
    ///Sets the map storing the distances calculated by the algorithm.
alpar@688
   185
    ///If you don't use this function before calling \ref run(),
alpar@688
   186
    ///it will allocate one. The destuctor deallocates this
alpar@688
   187
    ///automatically allocated map, of course.
alpar@688
   188
    ///\return <tt> (*this) </tt>
alpar@688
   189
    Dijkstra &setDistMap(DistMap &m) 
alpar@688
   190
    {
alpar@688
   191
      if(local_distance) {
alpar@688
   192
	delete distance;
alpar@688
   193
	local_distance=false;
alpar@688
   194
      }
alpar@688
   195
      distance = &m;
alpar@688
   196
      return *this;
alpar@688
   197
    }
alpar@255
   198
    
alpar@694
   199
  ///Runs %Dijkstra algorithm from node \c s.
alpar@694
   200
alpar@694
   201
  ///This method runs the %Dijkstra algorithm from a root node \c s
alpar@694
   202
  ///in order to
alpar@694
   203
  ///compute the
alpar@694
   204
  ///shortest path to each node. The algorithm computes
alpar@694
   205
  ///- The shortest path tree.
alpar@694
   206
  ///- The distance of each node from the root.
alpar@694
   207
    
alpar@694
   208
    void run(Node s) {
alpar@694
   209
      
alpar@694
   210
      init_maps();
alpar@694
   211
      
alpar@694
   212
      for ( NodeIt u(*G) ; G->valid(u) ; G->next(u) ) {
alpar@694
   213
	predecessor->set(u,INVALID);
alpar@694
   214
	pred_node->set(u,INVALID);
alpar@694
   215
      }
alpar@694
   216
      
alpar@694
   217
      typename GR::template NodeMap<int> heap_map(*G,-1);
alpar@694
   218
      
alpar@694
   219
      typedef Heap<Node, ValueType, typename GR::template NodeMap<int>,
alpar@694
   220
      std::less<ValueType> > 
alpar@694
   221
      HeapType;
alpar@694
   222
      
alpar@694
   223
      HeapType heap(heap_map);
alpar@694
   224
      
alpar@694
   225
      heap.push(s,0); 
alpar@694
   226
      
alpar@694
   227
      while ( !heap.empty() ) {
alpar@694
   228
	
alpar@694
   229
	Node v=heap.top(); 
alpar@694
   230
	ValueType oldvalue=heap[v];
alpar@694
   231
	heap.pop();
alpar@694
   232
	distance->set(v, oldvalue);
alpar@694
   233
	
alpar@694
   234
	
alpar@694
   235
	for(OutEdgeIt e(*G,v); G->valid(e); G->next(e)) {
alpar@694
   236
	  Node w=G->bNode(e); 
alpar@694
   237
	  
alpar@694
   238
	  switch(heap.state(w)) {
alpar@694
   239
	  case HeapType::PRE_HEAP:
alpar@694
   240
	    heap.push(w,oldvalue+(*length)[e]); 
alpar@694
   241
	    predecessor->set(w,e);
alpar@694
   242
	    pred_node->set(w,v);
alpar@694
   243
	    break;
alpar@694
   244
	  case HeapType::IN_HEAP:
alpar@694
   245
	    if ( oldvalue+(*length)[e] < heap[w] ) {
alpar@694
   246
	      heap.decrease(w, oldvalue+(*length)[e]); 
alpar@694
   247
	      predecessor->set(w,e);
alpar@694
   248
	      pred_node->set(w,v);
alpar@694
   249
	    }
alpar@694
   250
	    break;
alpar@694
   251
	  case HeapType::POST_HEAP:
alpar@694
   252
	    break;
alpar@694
   253
	  }
alpar@694
   254
	}
alpar@694
   255
      }
alpar@694
   256
    }
alpar@255
   257
    
jacint@385
   258
    ///The distance of a node from the root.
alpar@255
   259
jacint@385
   260
    ///Returns the distance of a node from the root.
alpar@255
   261
    ///\pre \ref run() must be called before using this function.
jacint@385
   262
    ///\warning If node \c v in unreachable from the root the return value
alpar@255
   263
    ///of this funcion is undefined.
alpar@688
   264
    ValueType dist(Node v) const { return (*distance)[v]; }
jacint@373
   265
alpar@584
   266
    ///Returns the 'previous edge' of the shortest path tree.
alpar@255
   267
alpar@584
   268
    ///For a node \c v it returns the 'previous edge' of the shortest path tree,
jacint@385
   269
    ///i.e. it returns the last edge from a shortest path from the root to \c
alpar@688
   270
    ///v. It is \ref INVALID
alpar@688
   271
    ///if \c v is unreachable from the root or if \c v=s. The
jacint@385
   272
    ///shortest path tree used here is equal to the shortest path tree used in
jacint@385
   273
    ///\ref predNode(Node v).  \pre \ref run() must be called before using
jacint@385
   274
    ///this function.
alpar@688
   275
    Edge pred(Node v) const { return (*predecessor)[v]; }
jacint@373
   276
alpar@584
   277
    ///Returns the 'previous node' of the shortest path tree.
alpar@255
   278
alpar@584
   279
    ///For a node \c v it returns the 'previous node' of the shortest path tree,
jacint@385
   280
    ///i.e. it returns the last but one node from a shortest path from the
jacint@385
   281
    ///root to \c /v. It is INVALID if \c v is unreachable from the root or if
jacint@385
   282
    ///\c v=s. The shortest path tree used here is equal to the shortest path
jacint@385
   283
    ///tree used in \ref pred(Node v).  \pre \ref run() must be called before
jacint@385
   284
    ///using this function.
alpar@688
   285
    Node predNode(Node v) const { return (*pred_node)[v]; }
alpar@255
   286
    
alpar@255
   287
    ///Returns a reference to the NodeMap of distances.
alpar@255
   288
jacint@385
   289
    ///Returns a reference to the NodeMap of distances. \pre \ref run() must
jacint@385
   290
    ///be called before using this function.
alpar@688
   291
    const DistMap &distMap() const { return *distance;}
jacint@385
   292
 
alpar@255
   293
    ///Returns a reference to the shortest path tree map.
alpar@255
   294
alpar@255
   295
    ///Returns a reference to the NodeMap of the edges of the
alpar@255
   296
    ///shortest path tree.
alpar@255
   297
    ///\pre \ref run() must be called before using this function.
alpar@688
   298
    const PredMap &predMap() const { return *predecessor;}
jacint@385
   299
 
jacint@385
   300
    ///Returns a reference to the map of nodes of shortest paths.
alpar@255
   301
alpar@255
   302
    ///Returns a reference to the NodeMap of the last but one nodes of the
jacint@385
   303
    ///shortest path tree.
alpar@255
   304
    ///\pre \ref run() must be called before using this function.
alpar@688
   305
    const PredNodeMap &predNodeMap() const { return *pred_node;}
alpar@255
   306
jacint@385
   307
    ///Checks if a node is reachable from the root.
alpar@255
   308
jacint@385
   309
    ///Returns \c true if \c v is reachable from the root.
jacint@385
   310
    ///\warning the root node is reported to be unreached!
alpar@255
   311
    ///\todo Is this what we want?
alpar@255
   312
    ///\pre \ref run() must be called before using this function.
jacint@385
   313
    ///
alpar@688
   314
    bool reached(Node v) { return G->valid((*predecessor)[v]); }
alpar@255
   315
    
alpar@255
   316
  };
alpar@255
   317
  
alpar@255
   318
alpar@255
   319
  // **********************************************************************
alpar@255
   320
  //  IMPLEMENTATIONS
alpar@255
   321
  // **********************************************************************
alpar@255
   322
alpar@430
   323
/// @}
alpar@255
   324
  
alpar@255
   325
} //END OF NAMESPACE HUGO
alpar@255
   326
alpar@255
   327
#endif
alpar@255
   328
alpar@255
   329