src/include/dijkstra.h
author alpar
Fri, 23 Apr 2004 13:31:34 +0000
changeset 382 f177fc597abd
parent 335 999eb3cd7b49
child 385 d7ebbae96025
permissions -rw-r--r--
(none)
alpar@255
     1
// -*- C++ -*-
alpar@255
     2
alpar@255
     3
#ifndef HUGO_DIJKSTRA_H
alpar@255
     4
#define HUGO_DIJKSTRA_H
alpar@255
     5
alpar@255
     6
///\file
alpar@255
     7
///\brief Dijkstra algorithm.
alpar@255
     8
alpar@257
     9
#include <fib_heap.h>
klao@258
    10
#include <bin_heap.h>
alpar@257
    11
#include <invalid.h>
alpar@255
    12
alpar@255
    13
namespace hugo {
alpar@255
    14
  
alpar@255
    15
  ///%Dijkstra algorithm class.
alpar@255
    16
alpar@255
    17
  ///This class provides an efficient implementation of %Dijkstra algorithm.
alpar@255
    18
  ///The edge lengths are passed to the algorithm using a
alpar@255
    19
  ///\ref ReadMapSkeleton "readable map",
alpar@255
    20
  ///so it is easy to change it to any kind of length.
alpar@255
    21
  ///
alpar@255
    22
  ///The type of the length is determined by the \c ValueType of the length map.
alpar@255
    23
  ///
alpar@255
    24
  ///It is also possible to change the underlying priority heap.
alpar@255
    25
  ///
jacint@373
    26
  ///\param Graph The graph type the algorithm runs on.  
jacint@373
    27
  ///\param LengthMap This read-only EdgeMap determines the lengths of
jacint@373
    28
  ///the edges. It is read once for each edge, so the map may involve
jacint@373
    29
  ///in relatively time consuming process to compute the edge length
jacint@373
    30
  ///if it is necessary. The default map type is \ref
jacint@373
    31
  ///GraphSkeleton::EdgeMap "Graph::EdgeMap<int>"
jacint@373
    32
  ///\param Heap The heap type used by the %Dijkstra algorithm. The
jacint@373
    33
  ///default is using \ref BinHeap "binary heap".
alpar@255
    34
  
alpar@255
    35
#ifdef DOXYGEN
alpar@255
    36
  template <typename Graph,
alpar@255
    37
	    typename LengthMap,
alpar@255
    38
	    typename Heap>
alpar@255
    39
#else
alpar@255
    40
  template <typename Graph,
alpar@255
    41
	    typename LengthMap=typename Graph::EdgeMap<int>,
alpar@255
    42
	    template <class,class,class> class Heap = BinHeap >
alpar@255
    43
#endif
alpar@255
    44
  class Dijkstra{
alpar@255
    45
  public:
alpar@255
    46
    typedef typename Graph::Node Node;
alpar@255
    47
    typedef typename Graph::NodeIt NodeIt;
alpar@255
    48
    typedef typename Graph::Edge Edge;
alpar@255
    49
    typedef typename Graph::OutEdgeIt OutEdgeIt;
alpar@255
    50
    
alpar@255
    51
    typedef typename LengthMap::ValueType ValueType;
alpar@255
    52
    typedef typename Graph::NodeMap<Edge> PredMap;
alpar@255
    53
    typedef typename Graph::NodeMap<Node> PredNodeMap;
alpar@255
    54
    typedef typename Graph::NodeMap<ValueType> DistMap;
alpar@255
    55
alpar@255
    56
  private:
alpar@255
    57
    const Graph& G;
alpar@255
    58
    const LengthMap& length;
alpar@255
    59
    PredMap predecessor;
alpar@255
    60
    PredNodeMap pred_node;
alpar@255
    61
    DistMap distance;
alpar@255
    62
    
alpar@255
    63
  public :
alpar@255
    64
    
alpar@255
    65
    Dijkstra(Graph& _G, LengthMap& _length) :
alpar@255
    66
      G(_G), length(_length), predecessor(_G), pred_node(_G), distance(_G) { }
alpar@255
    67
    
alpar@255
    68
    void run(Node s);
alpar@255
    69
    
alpar@255
    70
    ///The distance of a node from the source.
alpar@255
    71
alpar@255
    72
    ///Returns the distance of a node from the source.
alpar@255
    73
    ///\pre \ref run() must be called before using this function.
alpar@255
    74
    ///\warning If node \c v in unreachable from the source the return value
alpar@255
    75
    ///of this funcion is undefined.
alpar@255
    76
    ValueType dist(Node v) const { return distance[v]; }
jacint@373
    77
alpar@255
    78
    ///Returns the edges of the shortest path tree.
alpar@255
    79
alpar@255
    80
    ///For a node \c v it returns the last edge of the shortest path
alpar@255
    81
    ///from the source to \c v or INVALID if \c v is unreachable
alpar@255
    82
    ///from the source.
alpar@255
    83
    ///\pre \ref run() must be called before using this function.
alpar@255
    84
    Edge pred(Node v) const { return predecessor[v]; }
jacint@373
    85
alpar@255
    86
    ///Returns the nodes of the shortest paths.
alpar@255
    87
alpar@255
    88
    ///For a node \c v it returns the last but one node of the shortest path
alpar@255
    89
    ///from the source to \c v or INVALID if \c v is unreachable
alpar@255
    90
    ///from the source.
alpar@255
    91
    ///\pre \ref run() must be called before using this function.
alpar@255
    92
    Node predNode(Node v) const { return pred_node[v]; }
alpar@255
    93
    
alpar@255
    94
    ///Returns a reference to the NodeMap of distances.
alpar@255
    95
alpar@255
    96
    ///\pre \ref run() must be called before using this function.
alpar@255
    97
    ///
alpar@255
    98
    const DistMap &distMap() const { return distance;}
jacint@373
    99
    
alpar@255
   100
    ///Returns a reference to the shortest path tree map.
alpar@255
   101
alpar@255
   102
    ///Returns a reference to the NodeMap of the edges of the
alpar@255
   103
    ///shortest path tree.
alpar@255
   104
    ///\pre \ref run() must be called before using this function.
alpar@255
   105
    const PredMap &predMap() const { return predecessor;}
jacint@373
   106
    
alpar@255
   107
    ///Returns a reference to the map of nodes of  shortest paths.
alpar@255
   108
alpar@255
   109
    ///Returns a reference to the NodeMap of the last but one nodes of the
alpar@255
   110
    ///shortest paths.
alpar@255
   111
    ///\pre \ref run() must be called before using this function.
alpar@255
   112
    const PredNodeMap &predNodeMap() const { return pred_node;}
alpar@255
   113
alpar@255
   114
    ///Checks if a node is reachable from the source.
alpar@255
   115
alpar@255
   116
    ///Returns \c true if \c v is reachable from the source.
alpar@255
   117
    ///\warning the source node is reported to be unreached!
alpar@255
   118
    ///\todo Is this what we want?
alpar@255
   119
    ///\pre \ref run() must be called before using this function.
alpar@255
   120
    bool reached(Node v) { return G.valid(predecessor[v]); }
alpar@255
   121
    
alpar@255
   122
  };
alpar@255
   123
  
alpar@255
   124
alpar@255
   125
  // **********************************************************************
alpar@255
   126
  //  IMPLEMENTATIONS
alpar@255
   127
  // **********************************************************************
alpar@255
   128
jacint@373
   129
  ///Runs %Dijkstra algorithm from source node \c s.
alpar@255
   130
alpar@255
   131
  ///This method runs the %Dijkstra algorithm from a source node \c s
jacint@373
   132
  ///in order to compute the shortest path to each node. The algorithm
jacint@373
   133
  ///computes - The shortest path tree.  - The distance of each node
jacint@373
   134
  ///from the source.
alpar@255
   135
  template <typename Graph, typename LengthMap,
alpar@255
   136
	    template<class,class,class> class Heap >
alpar@255
   137
  void Dijkstra<Graph,LengthMap,Heap>::run(Node s) {
alpar@255
   138
    
alpar@255
   139
    NodeIt u;
alpar@255
   140
    for ( G.first(u) ; G.valid(u) ; G.next(u) ) {
alpar@255
   141
      predecessor.set(u,INVALID);
alpar@255
   142
      pred_node.set(u,INVALID);
alpar@255
   143
    }
alpar@255
   144
    
alpar@255
   145
    typename Graph::NodeMap<int> heap_map(G,-1);
alpar@255
   146
    
alpar@255
   147
    Heap<Node,ValueType,typename Graph::NodeMap<int> > heap(heap_map);
alpar@255
   148
    heap.push(s,0); 
alpar@255
   149
    
jacint@373
   150
    while ( !heap.empty() ) {
jacint@373
   151
      
jacint@373
   152
      Node v=heap.top(); 
jacint@373
   153
      ValueType oldvalue=heap[v];
jacint@373
   154
      heap.pop();
jacint@373
   155
      distance.set(v, oldvalue);
alpar@255
   156
	
jacint@373
   157
      { //FIXME this bracket is for e to be local
jacint@373
   158
	OutEdgeIt e;
jacint@373
   159
	for(G.first(e, v); G.valid(e); G.next(e)) {
alpar@255
   160
	  Node w=G.head(e); 
alpar@255
   161
	  
alpar@255
   162
	  switch(heap.state(w)) {
alpar@255
   163
	  case heap.PRE_HEAP:
alpar@255
   164
	    heap.push(w,oldvalue+length[e]); 
alpar@255
   165
	    predecessor.set(w,e);
alpar@255
   166
	    pred_node.set(w,v);
alpar@255
   167
	    break;
alpar@255
   168
	  case heap.IN_HEAP:
alpar@255
   169
	    if ( oldvalue+length[e] < heap[w] ) {
alpar@255
   170
	      heap.decrease(w, oldvalue+length[e]); 
alpar@255
   171
	      predecessor.set(w,e);
alpar@255
   172
	      pred_node.set(w,v);
alpar@255
   173
	    }
alpar@255
   174
	    break;
alpar@255
   175
	  case heap.POST_HEAP:
alpar@255
   176
	    break;
alpar@255
   177
	  }
alpar@255
   178
	}
jacint@373
   179
      } //FIXME this bracket
jacint@373
   180
    }
alpar@255
   181
  }
alpar@255
   182
  
alpar@255
   183
} //END OF NAMESPACE HUGO
alpar@255
   184
alpar@255
   185
#endif
alpar@255
   186
alpar@255
   187