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