src/hugo/dijkstra.h
author marci
Mon, 17 May 2004 06:32:12 +0000
changeset 644 d84f3d42237d
parent 570 eec0a62979c9
child 688 bdc429a557f2
permissions -rw-r--r--
#ifndef correction
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@456
    40
  ///\author Jacint Szabo
alpar@584
    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@584
    63
    ///The the type of the map that stores the edge lengths.
alpar@584
    64
    typedef LM LengthMap;
alpar@584
    65
    ///\brief The 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@584
    68
    ///\brief The 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@584
    71
    ///The 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@255
    75
    const Graph& G;
alpar@584
    76
    const LM& length;
alpar@255
    77
    PredMap predecessor;
alpar@255
    78
    PredNodeMap pred_node;
alpar@255
    79
    DistMap distance;
alpar@255
    80
    
alpar@255
    81
  public :
alpar@255
    82
    
alpar@584
    83
    Dijkstra(const Graph& _G, const LM& _length) :
alpar@255
    84
      G(_G), length(_length), predecessor(_G), pred_node(_G), distance(_G) { }
alpar@255
    85
    
alpar@255
    86
    void run(Node s);
alpar@255
    87
    
jacint@385
    88
    ///The distance of a node from the root.
alpar@255
    89
jacint@385
    90
    ///Returns the distance of a node from the root.
alpar@255
    91
    ///\pre \ref run() must be called before using this function.
jacint@385
    92
    ///\warning If node \c v in unreachable from the root the return value
alpar@255
    93
    ///of this funcion is undefined.
alpar@255
    94
    ValueType dist(Node v) const { return distance[v]; }
jacint@373
    95
alpar@584
    96
    ///Returns the 'previous edge' of the shortest path tree.
alpar@255
    97
alpar@584
    98
    ///For a node \c v it returns the 'previous edge' of the shortest path tree,
jacint@385
    99
    ///i.e. it returns the last edge from a shortest path from the root to \c
jacint@385
   100
    ///v. It is INVALID if \c v is unreachable from the root or if \c v=s. The
jacint@385
   101
    ///shortest path tree used here is equal to the shortest path tree used in
jacint@385
   102
    ///\ref predNode(Node v).  \pre \ref run() must be called before using
jacint@385
   103
    ///this function.
alpar@255
   104
    Edge pred(Node v) const { return predecessor[v]; }
jacint@373
   105
alpar@584
   106
    ///Returns the 'previous node' of the shortest path tree.
alpar@255
   107
alpar@584
   108
    ///For a node \c v it returns the 'previous node' of the shortest path tree,
jacint@385
   109
    ///i.e. it returns the last but one node from a shortest path from the
jacint@385
   110
    ///root to \c /v. It is INVALID if \c v is unreachable from the root or if
jacint@385
   111
    ///\c v=s. The shortest path tree used here is equal to the shortest path
jacint@385
   112
    ///tree used in \ref pred(Node v).  \pre \ref run() must be called before
jacint@385
   113
    ///using this function.
alpar@255
   114
    Node predNode(Node v) const { return pred_node[v]; }
alpar@255
   115
    
alpar@255
   116
    ///Returns a reference to the NodeMap of distances.
alpar@255
   117
jacint@385
   118
    ///Returns a reference to the NodeMap of distances. \pre \ref run() must
jacint@385
   119
    ///be called before using this function.
alpar@255
   120
    const DistMap &distMap() const { return distance;}
jacint@385
   121
 
alpar@255
   122
    ///Returns a reference to the shortest path tree map.
alpar@255
   123
alpar@255
   124
    ///Returns a reference to the NodeMap of the edges of the
alpar@255
   125
    ///shortest path tree.
alpar@255
   126
    ///\pre \ref run() must be called before using this function.
alpar@255
   127
    const PredMap &predMap() const { return predecessor;}
jacint@385
   128
 
jacint@385
   129
    ///Returns a reference to the map of nodes of shortest paths.
alpar@255
   130
alpar@255
   131
    ///Returns a reference to the NodeMap of the last but one nodes of the
jacint@385
   132
    ///shortest path tree.
alpar@255
   133
    ///\pre \ref run() must be called before using this function.
alpar@255
   134
    const PredNodeMap &predNodeMap() const { return pred_node;}
alpar@255
   135
jacint@385
   136
    ///Checks if a node is reachable from the root.
alpar@255
   137
jacint@385
   138
    ///Returns \c true if \c v is reachable from the root.
jacint@385
   139
    ///\warning the root node is reported to be unreached!
alpar@255
   140
    ///\todo Is this what we want?
alpar@255
   141
    ///\pre \ref run() must be called before using this function.
jacint@385
   142
    ///
alpar@255
   143
    bool reached(Node v) { return G.valid(predecessor[v]); }
alpar@255
   144
    
alpar@255
   145
  };
alpar@255
   146
  
alpar@255
   147
alpar@255
   148
  // **********************************************************************
alpar@255
   149
  //  IMPLEMENTATIONS
alpar@255
   150
  // **********************************************************************
alpar@255
   151
jacint@385
   152
  ///Runs %Dijkstra algorithm from node the root.
alpar@255
   153
jacint@385
   154
  ///This method runs the %Dijkstra algorithm from a root node \c s
jacint@385
   155
  ///in order to
jacint@385
   156
  ///compute the
jacint@385
   157
  ///shortest path to each node. The algorithm computes
jacint@385
   158
  ///- The shortest path tree.
jacint@385
   159
  ///- The distance of each node from the root.
alpar@584
   160
  template <typename GR, typename LM,
alpar@532
   161
	    template<class,class,class,class> class Heap >
alpar@584
   162
  void Dijkstra<GR,LM,Heap>::run(Node s) {
alpar@255
   163
    
alpar@255
   164
    NodeIt u;
alpar@255
   165
    for ( G.first(u) ; G.valid(u) ; G.next(u) ) {
alpar@255
   166
      predecessor.set(u,INVALID);
alpar@255
   167
      pred_node.set(u,INVALID);
alpar@255
   168
    }
alpar@255
   169
    
alpar@584
   170
    typename GR::template NodeMap<int> heap_map(G,-1);
alpar@255
   171
    
alpar@584
   172
    typedef Heap<Node, ValueType, typename GR::template NodeMap<int>,
alpar@532
   173
      std::less<ValueType> > 
alpar@532
   174
      HeapType;
alpar@532
   175
    
alpar@532
   176
    HeapType heap(heap_map);
jacint@385
   177
    
alpar@255
   178
    heap.push(s,0); 
alpar@255
   179
    
jacint@385
   180
      while ( !heap.empty() ) {
alpar@255
   181
	
jacint@385
   182
	Node v=heap.top(); 
jacint@385
   183
	ValueType oldvalue=heap[v];
jacint@385
   184
	heap.pop();
jacint@385
   185
	distance.set(v, oldvalue);
jacint@385
   186
	
jacint@385
   187
	{ //FIXME this bracket is for e to be local
jacint@385
   188
	  OutEdgeIt e;
jacint@385
   189
	for(G.first(e, v);
jacint@385
   190
	    G.valid(e); G.next(e)) {
marci@421
   191
	  Node w=G.bNode(e); 
alpar@255
   192
	  
alpar@255
   193
	  switch(heap.state(w)) {
alpar@532
   194
	  case HeapType::PRE_HEAP:
alpar@255
   195
	    heap.push(w,oldvalue+length[e]); 
alpar@255
   196
	    predecessor.set(w,e);
alpar@255
   197
	    pred_node.set(w,v);
alpar@255
   198
	    break;
alpar@532
   199
	  case HeapType::IN_HEAP:
alpar@255
   200
	    if ( oldvalue+length[e] < heap[w] ) {
alpar@255
   201
	      heap.decrease(w, oldvalue+length[e]); 
alpar@255
   202
	      predecessor.set(w,e);
alpar@255
   203
	      pred_node.set(w,v);
alpar@255
   204
	    }
alpar@255
   205
	    break;
alpar@532
   206
	  case HeapType::POST_HEAP:
alpar@255
   207
	    break;
alpar@255
   208
	  }
alpar@255
   209
	}
jacint@385
   210
      } //FIXME tis bracket
jacint@385
   211
      }
alpar@255
   212
  }
alpar@430
   213
alpar@430
   214
/// @}
alpar@255
   215
  
alpar@255
   216
} //END OF NAMESPACE HUGO
alpar@255
   217
alpar@255
   218
#endif
alpar@255
   219
alpar@255
   220