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