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