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