src/hugo/dijkstra.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000
changeset 822 88226d9fe821
parent 785 a9b0863c2265
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
alpar@758
     5
///\ingroup flowalgs
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@758
    14
/// \addtogroup flowalgs
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@734
    42
  ///\todo Type of \c PredMap, \c PredNodeMap and \c DistMap
alpar@734
    43
  ///should not be fixed. (Problematic to solve).
alpar@584
    44
alpar@255
    45
#ifdef DOXYGEN
alpar@584
    46
  template <typename GR,
alpar@584
    47
	    typename LM,
alpar@255
    48
	    typename Heap>
alpar@255
    49
#else
alpar@584
    50
  template <typename GR,
alpar@584
    51
	    typename LM=typename GR::template EdgeMap<int>,
alpar@532
    52
	    template <class,class,class,class> class Heap = BinHeap >
alpar@255
    53
#endif
alpar@255
    54
  class Dijkstra{
alpar@255
    55
  public:
alpar@584
    56
    ///The type of the underlying graph.
alpar@584
    57
    typedef GR Graph;
alpar@802
    58
    ///.
alpar@255
    59
    typedef typename Graph::Node Node;
alpar@802
    60
    ///.
alpar@255
    61
    typedef typename Graph::NodeIt NodeIt;
alpar@802
    62
    ///.
alpar@255
    63
    typedef typename Graph::Edge Edge;
alpar@802
    64
    ///.
alpar@255
    65
    typedef typename Graph::OutEdgeIt OutEdgeIt;
alpar@255
    66
    
alpar@584
    67
    ///The type of the length of the edges.
alpar@584
    68
    typedef typename LM::ValueType ValueType;
alpar@693
    69
    ///The type of the map that stores the edge lengths.
alpar@584
    70
    typedef LM LengthMap;
alpar@693
    71
    ///\brief The type of the map that stores the last
alpar@584
    72
    ///edges of the shortest paths.
marci@433
    73
    typedef typename Graph::template NodeMap<Edge> PredMap;
alpar@693
    74
    ///\brief The type of the map that stores the last but one
alpar@584
    75
    ///nodes of the shortest paths.
marci@433
    76
    typedef typename Graph::template NodeMap<Node> PredNodeMap;
alpar@693
    77
    ///The type of the map that stores the dists of the nodes.
marci@433
    78
    typedef typename Graph::template NodeMap<ValueType> DistMap;
alpar@255
    79
alpar@255
    80
  private:
alpar@802
    81
    /// Pointer to the underlying graph.
alpar@688
    82
    const Graph *G;
alpar@802
    83
    /// Pointer to the length map
alpar@688
    84
    const LM *length;
alpar@802
    85
    ///Pointer to the map of predecessors edges.
alpar@688
    86
    PredMap *predecessor;
alpar@802
    87
    ///Indicates if \ref predecessor is locally allocated (\c true) or not.
alpar@688
    88
    bool local_predecessor;
alpar@802
    89
    ///Pointer to the map of predecessors nodes.
alpar@688
    90
    PredNodeMap *pred_node;
alpar@802
    91
    ///Indicates if \ref pred_node is locally allocated (\c true) or not.
alpar@688
    92
    bool local_pred_node;
alpar@802
    93
    ///Pointer to the map of distances.
alpar@688
    94
    DistMap *distance;
alpar@802
    95
    ///Indicates if \ref distance is locally allocated (\c true) or not.
alpar@688
    96
    bool local_distance;
alpar@688
    97
alpar@802
    98
    ///The source node of the last execution.
alpar@774
    99
    Node source;
alpar@774
   100
alpar@785
   101
    ///Initializes the maps.
alpar@688
   102
    
alpar@694
   103
    ///\todo Error if \c G or are \c NULL. What about \c length?
alpar@688
   104
    ///\todo Better memory allocation (instead of new).
alpar@688
   105
    void init_maps() 
alpar@688
   106
    {
alpar@688
   107
      if(!predecessor) {
alpar@688
   108
	local_predecessor = true;
alpar@688
   109
	predecessor = new PredMap(*G);
alpar@688
   110
      }
alpar@688
   111
      if(!pred_node) {
alpar@688
   112
	local_pred_node = true;
alpar@688
   113
	pred_node = new PredNodeMap(*G);
alpar@688
   114
      }
alpar@688
   115
      if(!distance) {
alpar@688
   116
	local_distance = true;
alpar@688
   117
	distance = new DistMap(*G);
alpar@688
   118
      }
alpar@688
   119
    }
alpar@255
   120
    
alpar@255
   121
  public :
alpar@802
   122
    ///Constructor.
alpar@255
   123
    
alpar@802
   124
    ///\param _G the graph the algorithm will run on.
alpar@802
   125
    ///\param _length the length map used by the algorithm.
alpar@584
   126
    Dijkstra(const Graph& _G, const LM& _length) :
alpar@688
   127
      G(&_G), length(&_length),
alpar@707
   128
      predecessor(NULL), local_predecessor(false),
alpar@707
   129
      pred_node(NULL), local_pred_node(false),
alpar@707
   130
      distance(NULL), local_distance(false)
alpar@688
   131
    { }
alpar@688
   132
    
alpar@802
   133
    ///Destructor.
alpar@688
   134
    ~Dijkstra() 
alpar@688
   135
    {
alpar@688
   136
      if(local_predecessor) delete predecessor;
alpar@688
   137
      if(local_pred_node) delete pred_node;
alpar@688
   138
      if(local_distance) delete distance;
alpar@688
   139
    }
alpar@688
   140
alpar@688
   141
    ///Sets the length map.
alpar@688
   142
alpar@688
   143
    ///Sets the length map.
alpar@688
   144
    ///\return <tt> (*this) </tt>
alpar@688
   145
    Dijkstra &setLengthMap(const LM &m) 
alpar@688
   146
    {
alpar@688
   147
      length = &m;
alpar@688
   148
      return *this;
alpar@688
   149
    }
alpar@688
   150
alpar@688
   151
    ///Sets the map storing the predecessor edges.
alpar@688
   152
alpar@688
   153
    ///Sets the map storing the predecessor edges.
alpar@688
   154
    ///If you don't use this function before calling \ref run(),
alpar@688
   155
    ///it will allocate one. The destuctor deallocates this
alpar@688
   156
    ///automatically allocated map, of course.
alpar@688
   157
    ///\return <tt> (*this) </tt>
alpar@688
   158
    Dijkstra &setPredMap(PredMap &m) 
alpar@688
   159
    {
alpar@688
   160
      if(local_predecessor) {
alpar@688
   161
	delete predecessor;
alpar@688
   162
	local_predecessor=false;
alpar@688
   163
      }
alpar@688
   164
      predecessor = &m;
alpar@688
   165
      return *this;
alpar@688
   166
    }
alpar@688
   167
alpar@688
   168
    ///Sets the map storing the predecessor nodes.
alpar@688
   169
alpar@688
   170
    ///Sets the map storing the predecessor nodes.
alpar@688
   171
    ///If you don't use this function before calling \ref run(),
alpar@688
   172
    ///it will allocate one. The destuctor deallocates this
alpar@688
   173
    ///automatically allocated map, of course.
alpar@688
   174
    ///\return <tt> (*this) </tt>
alpar@688
   175
    Dijkstra &setPredNodeMap(PredNodeMap &m) 
alpar@688
   176
    {
alpar@688
   177
      if(local_pred_node) {
alpar@688
   178
	delete pred_node;
alpar@688
   179
	local_pred_node=false;
alpar@688
   180
      }
alpar@688
   181
      pred_node = &m;
alpar@688
   182
      return *this;
alpar@688
   183
    }
alpar@688
   184
alpar@688
   185
    ///Sets the map storing the distances calculated by the algorithm.
alpar@688
   186
alpar@688
   187
    ///Sets the map storing the distances calculated by the algorithm.
alpar@688
   188
    ///If you don't use this function before calling \ref run(),
alpar@688
   189
    ///it will allocate one. The destuctor deallocates this
alpar@688
   190
    ///automatically allocated map, of course.
alpar@688
   191
    ///\return <tt> (*this) </tt>
alpar@688
   192
    Dijkstra &setDistMap(DistMap &m) 
alpar@688
   193
    {
alpar@688
   194
      if(local_distance) {
alpar@688
   195
	delete distance;
alpar@688
   196
	local_distance=false;
alpar@688
   197
      }
alpar@688
   198
      distance = &m;
alpar@688
   199
      return *this;
alpar@688
   200
    }
alpar@255
   201
    
alpar@694
   202
  ///Runs %Dijkstra algorithm from node \c s.
alpar@694
   203
alpar@694
   204
  ///This method runs the %Dijkstra algorithm from a root node \c s
alpar@694
   205
  ///in order to
alpar@694
   206
  ///compute the
alpar@694
   207
  ///shortest path to each node. The algorithm computes
alpar@694
   208
  ///- The shortest path tree.
alpar@694
   209
  ///- The distance of each node from the root.
alpar@694
   210
    
alpar@694
   211
    void run(Node s) {
alpar@694
   212
      
alpar@694
   213
      init_maps();
alpar@694
   214
      
alpar@774
   215
      source = s;
alpar@774
   216
      
alpar@774
   217
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
alpar@694
   218
	predecessor->set(u,INVALID);
alpar@694
   219
	pred_node->set(u,INVALID);
alpar@694
   220
      }
alpar@694
   221
      
alpar@694
   222
      typename GR::template NodeMap<int> heap_map(*G,-1);
alpar@694
   223
      
alpar@694
   224
      typedef Heap<Node, ValueType, typename GR::template NodeMap<int>,
alpar@694
   225
      std::less<ValueType> > 
alpar@694
   226
      HeapType;
alpar@694
   227
      
alpar@694
   228
      HeapType heap(heap_map);
alpar@694
   229
      
alpar@694
   230
      heap.push(s,0); 
alpar@694
   231
      
alpar@694
   232
      while ( !heap.empty() ) {
alpar@694
   233
	
alpar@694
   234
	Node v=heap.top(); 
alpar@694
   235
	ValueType oldvalue=heap[v];
alpar@694
   236
	heap.pop();
alpar@694
   237
	distance->set(v, oldvalue);
alpar@694
   238
	
alpar@694
   239
	
alpar@774
   240
	for(OutEdgeIt e(*G,v); e!=INVALID; ++e) {
alpar@774
   241
	  Node w=G->head(e); 
alpar@694
   242
	  switch(heap.state(w)) {
alpar@694
   243
	  case HeapType::PRE_HEAP:
alpar@694
   244
	    heap.push(w,oldvalue+(*length)[e]); 
alpar@694
   245
	    predecessor->set(w,e);
alpar@694
   246
	    pred_node->set(w,v);
alpar@694
   247
	    break;
alpar@694
   248
	  case HeapType::IN_HEAP:
alpar@694
   249
	    if ( oldvalue+(*length)[e] < heap[w] ) {
alpar@694
   250
	      heap.decrease(w, oldvalue+(*length)[e]); 
alpar@694
   251
	      predecessor->set(w,e);
alpar@694
   252
	      pred_node->set(w,v);
alpar@694
   253
	    }
alpar@694
   254
	    break;
alpar@694
   255
	  case HeapType::POST_HEAP:
alpar@694
   256
	    break;
alpar@694
   257
	  }
alpar@694
   258
	}
alpar@694
   259
      }
alpar@694
   260
    }
alpar@255
   261
    
jacint@385
   262
    ///The distance of a node from the root.
alpar@255
   263
jacint@385
   264
    ///Returns the distance of a node from the root.
alpar@255
   265
    ///\pre \ref run() must be called before using this function.
jacint@385
   266
    ///\warning If node \c v in unreachable from the root the return value
alpar@255
   267
    ///of this funcion is undefined.
alpar@688
   268
    ValueType dist(Node v) const { return (*distance)[v]; }
jacint@373
   269
alpar@584
   270
    ///Returns the 'previous edge' of the shortest path tree.
alpar@255
   271
alpar@584
   272
    ///For a node \c v it returns the 'previous edge' of the shortest path tree,
alpar@785
   273
    ///i.e. it returns the last edge of a shortest path from the root to \c
alpar@688
   274
    ///v. It is \ref INVALID
alpar@688
   275
    ///if \c v is unreachable from the root or if \c v=s. The
jacint@385
   276
    ///shortest path tree used here is equal to the shortest path tree used in
jacint@385
   277
    ///\ref predNode(Node v).  \pre \ref run() must be called before using
jacint@385
   278
    ///this function.
alpar@780
   279
    ///\todo predEdge could be a better name.
alpar@688
   280
    Edge pred(Node v) const { return (*predecessor)[v]; }
jacint@373
   281
alpar@584
   282
    ///Returns the 'previous node' of the shortest path tree.
alpar@255
   283
alpar@584
   284
    ///For a node \c v it returns the 'previous node' of the shortest path tree,
jacint@385
   285
    ///i.e. it returns the last but one node from a shortest path from the
jacint@385
   286
    ///root to \c /v. It is INVALID if \c v is unreachable from the root or if
jacint@385
   287
    ///\c v=s. The shortest path tree used here is equal to the shortest path
jacint@385
   288
    ///tree used in \ref pred(Node v).  \pre \ref run() must be called before
jacint@385
   289
    ///using this function.
alpar@688
   290
    Node predNode(Node v) const { return (*pred_node)[v]; }
alpar@255
   291
    
alpar@255
   292
    ///Returns a reference to the NodeMap of distances.
alpar@255
   293
jacint@385
   294
    ///Returns a reference to the NodeMap of distances. \pre \ref run() must
jacint@385
   295
    ///be called before using this function.
alpar@688
   296
    const DistMap &distMap() const { return *distance;}
jacint@385
   297
 
alpar@255
   298
    ///Returns a reference to the shortest path tree map.
alpar@255
   299
alpar@255
   300
    ///Returns a reference to the NodeMap of the edges of the
alpar@255
   301
    ///shortest path tree.
alpar@255
   302
    ///\pre \ref run() must be called before using this function.
alpar@688
   303
    const PredMap &predMap() const { return *predecessor;}
jacint@385
   304
 
jacint@385
   305
    ///Returns a reference to the map of nodes of shortest paths.
alpar@255
   306
alpar@255
   307
    ///Returns a reference to the NodeMap of the last but one nodes of the
jacint@385
   308
    ///shortest path tree.
alpar@255
   309
    ///\pre \ref run() must be called before using this function.
alpar@688
   310
    const PredNodeMap &predNodeMap() const { return *pred_node;}
alpar@255
   311
jacint@385
   312
    ///Checks if a node is reachable from the root.
alpar@255
   313
jacint@385
   314
    ///Returns \c true if \c v is reachable from the root.
alpar@802
   315
    ///\note The root node is reported to be reached!
alpar@255
   316
    ///\pre \ref run() must be called before using this function.
jacint@385
   317
    ///
alpar@780
   318
    bool reached(Node v) { return v==source || (*predecessor)[v]!=INVALID; }
alpar@255
   319
    
alpar@255
   320
  };
alpar@255
   321
  
alpar@430
   322
/// @}
alpar@255
   323
  
alpar@255
   324
} //END OF NAMESPACE HUGO
alpar@255
   325
alpar@255
   326
#endif
alpar@255
   327
alpar@255
   328