jacint@159: // -*- C++ -*- jacint@372: jacint@159: /* jacint@211: *template > jacint@159: * jacint@159: *Constructor: jacint@159: * jacint@211: *Dijkstra(Graph G, LengthMap length) jacint@159: * jacint@159: * jacint@211: *Methods: jacint@159: * jacint@211: *void run(Node s) jacint@159: * jacint@211: *T dist(Node v) : After run(s) was run, it returns the distance from s to v. jacint@211: * Returns T() if v is not reachable from s. jacint@159: * jacint@211: *Edge pred(Node v) : After run(s) was run, it returns the last jacint@211: * edge of a shortest s-v path. It is INVALID for s and for jacint@211: * the nodes not reachable from s. jacint@159: * jacint@211: *bool reached(Node v) : After run(s) was run, it is true iff v is jacint@211: * reachable from s jacint@159: * jacint@159: */ jacint@159: jacint@211: #ifndef HUGO_DIJKSTRA_H jacint@211: #define HUGO_DIJKSTRA_H jacint@159: jacint@372: ///\file jacint@372: ///\brief Dijkstra algorithm. jacint@372: jacint@159: #include jacint@372: #include jacint@211: #include jacint@159: jacint@159: namespace hugo { jacint@211: jacint@372: //Alpar: Changed the order of the parameters jacint@372: jacint@372: ///%Dijkstra algorithm class. jacint@372: jacint@372: ///This class provides an efficient implementation of %Dijkstra algorithm. jacint@372: ///The edge lengths are passed to the algorithm using a jacint@372: ///\ref ReadMapSkeleton "readable map", jacint@372: ///so it is easy to change it to any kind of length. jacint@372: /// jacint@372: ///The type of the length is determined by the \c ValueType of the length map. jacint@372: /// jacint@372: ///It is also possible to change the underlying priority heap. jacint@372: /// jacint@372: ///\param Graph The graph type the algorithm runs on. jacint@372: ///\param LengthMap This read-only jacint@372: ///EdgeMap jacint@372: ///determines the jacint@372: ///lengths of the edges. It is read once for each edge, so the map jacint@372: ///may involve in relatively time consuming process to compute the edge jacint@372: ///length if it is necessary. The default map type is jacint@372: ///\ref GraphSkeleton::EdgeMap "Graph::EdgeMap" jacint@372: ///\param Heap The heap type used by the %Dijkstra jacint@372: ///algorithm. The default jacint@372: ///is using \ref BinHeap "binary heap". jacint@372: jacint@372: #ifdef DOXYGEN jacint@372: template jacint@372: #else jacint@372: template , jacint@372: template class Heap = BinHeap > jacint@372: #endif jacint@211: class Dijkstra{ jacint@372: public: jacint@211: typedef typename Graph::Node Node; jacint@211: typedef typename Graph::NodeIt NodeIt; jacint@211: typedef typename Graph::Edge Edge; jacint@211: typedef typename Graph::OutEdgeIt OutEdgeIt; jacint@211: jacint@372: typedef typename LengthMap::ValueType ValueType; jacint@372: typedef typename Graph::NodeMap PredMap; jacint@372: typedef typename Graph::NodeMap PredNodeMap; jacint@372: typedef typename Graph::NodeMap DistMap; jacint@372: jacint@372: private: jacint@211: const Graph& G; jacint@211: const LengthMap& length; jacint@372: PredMap predecessor; jacint@372: PredNodeMap pred_node; jacint@372: DistMap distance; jacint@211: jacint@159: public : jacint@211: jacint@372: Dijkstra(Graph& _G, LengthMap& _length) : jacint@372: G(_G), length(_length), predecessor(_G), pred_node(_G), distance(_G) { } jacint@159: jacint@372: void run(Node s); jacint@372: jacint@372: ///The distance of a node from the source. jacint@211: jacint@372: ///Returns the distance of a node from the source. jacint@372: ///\pre \ref run() must be called before using this function. jacint@372: ///\warning If node \c v in unreachable from the source the return value jacint@372: ///of this funcion is undefined. jacint@372: ValueType dist(Node v) const { return distance[v]; } jacint@372: ///Returns the edges of the shortest path tree. jacint@211: jacint@372: ///For a node \c v it returns the last edge of the shortest path jacint@372: ///from the source to \c v or INVALID if \c v is unreachable jacint@372: ///from the source. jacint@372: ///\pre \ref run() must be called before using this function. jacint@372: Edge pred(Node v) const { return predecessor[v]; } jacint@372: ///Returns the nodes of the shortest paths. jacint@211: jacint@372: ///For a node \c v it returns the last but one node of the shortest path jacint@372: ///from the source to \c v or INVALID if \c v is unreachable jacint@372: ///from the source. jacint@372: ///\pre \ref run() must be called before using this function. jacint@372: Node predNode(Node v) const { return pred_node[v]; } jacint@372: jacint@372: ///Returns a reference to the NodeMap of distances. jacint@372: jacint@372: ///\pre \ref run() must be called before using this function. jacint@372: /// jacint@372: const DistMap &distMap() const { return distance;} jacint@372: ///Returns a reference to the shortest path tree map. jacint@372: jacint@372: ///Returns a reference to the NodeMap of the edges of the jacint@372: ///shortest path tree. jacint@372: ///\pre \ref run() must be called before using this function. jacint@372: const PredMap &predMap() const { return predecessor;} jacint@372: ///Returns a reference to the map of nodes of shortest paths. jacint@372: jacint@372: ///Returns a reference to the NodeMap of the last but one nodes of the jacint@372: ///shortest paths. jacint@372: ///\pre \ref run() must be called before using this function. jacint@372: const PredNodeMap &predNodeMap() const { return pred_node;} jacint@372: jacint@372: ///Checks if a node is reachable from the source. jacint@372: jacint@372: ///Returns \c true if \c v is reachable from the source. jacint@372: ///\warning the source node is reported to be unreached! jacint@372: ///\todo Is this what we want? jacint@372: ///\pre \ref run() must be called before using this function. jacint@372: /// jacint@372: bool reached(Node v) { return G.valid(predecessor[v]); } jacint@372: jacint@372: }; jacint@372: jacint@372: jacint@372: // ********************************************************************** jacint@372: // IMPLEMENTATIONS jacint@372: // ********************************************************************** jacint@372: jacint@372: ///Runs %Dijkstra algorithm from node the source. jacint@372: jacint@372: ///This method runs the %Dijkstra algorithm from a source node \c s jacint@372: ///in order to jacint@372: ///compute the jacint@372: ///shortest path to each node. The algorithm computes jacint@372: ///- The shortest path tree. jacint@372: ///- The distance of each node from the source. jacint@372: template class Heap > jacint@372: void Dijkstra::run(Node s) { jacint@372: jacint@372: NodeIt u; jacint@372: for ( G.first(u) ; G.valid(u) ; G.next(u) ) { jacint@372: predecessor.set(u,INVALID); jacint@372: pred_node.set(u,INVALID); jacint@372: // If a node is unreacheable, then why should be the dist=0? jacint@372: // distance.set(u,0); jacint@372: // reach.set(u,false); jacint@372: } jacint@372: jacint@372: typename Graph::NodeMap heap_map(G,-1); jacint@372: jacint@372: Heap > heap(heap_map); jacint@372: jacint@372: heap.push(s,0); jacint@372: jacint@211: while ( !heap.empty() ) { jacint@159: jacint@211: Node v=heap.top(); jacint@372: ValueType oldvalue=heap[v]; jacint@211: heap.pop(); jacint@211: distance.set(v, oldvalue); jacint@372: jacint@372: { //FIXME this bracket is for e to be local jacint@372: OutEdgeIt e; jacint@372: for(G.first(e, v); jacint@372: G.valid(e); G.next(e)) { jacint@211: Node w=G.head(e); jacint@372: jacint@372: switch(heap.state(w)) { jacint@372: case heap.PRE_HEAP: jacint@372: heap.push(w,oldvalue+length[e]); jacint@372: predecessor.set(w,e); jacint@372: pred_node.set(w,v); jacint@372: break; jacint@372: case heap.IN_HEAP: jacint@372: if ( oldvalue+length[e] < heap[w] ) { jacint@372: heap.decrease(w, oldvalue+length[e]); jacint@211: predecessor.set(w,e); jacint@372: pred_node.set(w,v); jacint@159: } jacint@372: break; jacint@372: case heap.POST_HEAP: jacint@372: break; jacint@159: } jacint@159: } jacint@372: } //FIXME tis bracket jacint@211: } jacint@372: } jacint@167: jacint@372: } //END OF NAMESPACE HUGO jacint@159: jacint@159: #endif jacint@159: jacint@159: