alpar@906: /* -*- C++ -*- alpar@921: * src/lemon/dijkstra.h - Part of LEMON, a generic C++ optimization library alpar@906: * alpar@1164: * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@906: * (Egervary Combinatorial Optimization Research Group, EGRES). alpar@906: * alpar@906: * Permission to use, modify and distribute this software is granted alpar@906: * provided that this copyright notice appears in all copies. For alpar@906: * precise terms see the accompanying LICENSE file. alpar@906: * alpar@906: * This software is provided "AS IS" with no warranty of any kind, alpar@906: * express or implied, and with no claim as to its suitability for any alpar@906: * purpose. alpar@906: * alpar@906: */ alpar@906: alpar@921: #ifndef LEMON_DIJKSTRA_H alpar@921: #define LEMON_DIJKSTRA_H alpar@255: alpar@758: ///\ingroup flowalgs alpar@255: ///\file alpar@255: ///\brief Dijkstra algorithm. alpar@255: alpar@953: #include alpar@921: #include alpar@921: #include alpar@1119: #include alpar@1119: #include alpar@255: alpar@921: namespace lemon { jacint@385: alpar@1119: alpar@1151: alpar@954: ///Default traits class of Dijkstra class. alpar@954: alpar@954: ///Default traits class of Dijkstra class. alpar@954: ///\param GR Graph type. alpar@954: ///\param LM Type of length map. alpar@953: template alpar@953: struct DijkstraDefaultTraits alpar@953: { alpar@954: ///The graph type the algorithm runs on. alpar@953: typedef GR Graph; alpar@953: ///The type of the map that stores the edge lengths. alpar@953: hegyi@1124: ///The type of the map that stores the edge lengths. alpar@967: ///It must meet the \ref concept::ReadMap "ReadMap" concept. alpar@953: typedef LM LengthMap; alpar@954: //The type of the length of the edges. alpar@987: typedef typename LM::Value Value; alpar@954: ///The heap type used by Dijkstra algorithm. alpar@967: alpar@967: ///The heap type used by Dijkstra algorithm. alpar@967: /// alpar@967: ///\sa BinHeap alpar@967: ///\sa Dijkstra alpar@953: typedef BinHeap, alpar@987: std::less > Heap; alpar@953: alpar@953: ///\brief The type of the map that stores the last alpar@953: ///edges of the shortest paths. alpar@953: /// hegyi@1124: ///The type of the map that stores the last hegyi@1124: ///edges of the shortest paths. alpar@967: ///It must meet the \ref concept::WriteMap "WriteMap" concept. alpar@953: /// alpar@954: typedef typename Graph::template NodeMap PredMap; alpar@954: ///Instantiates a PredMap. alpar@953: hegyi@1123: ///This function instantiates a \ref PredMap. hegyi@1123: ///\param G is the graph, to which we would like to define the PredMap. alpar@1119: ///\todo The graph alone may be insufficient for the initialization alpar@954: static PredMap *createPredMap(const GR &G) alpar@953: { alpar@953: return new PredMap(G); alpar@953: } alpar@1218: // ///\brief The type of the map that stores the last but one alpar@1218: // ///nodes of the shortest paths. alpar@1218: // /// alpar@1218: // ///The type of the map that stores the last but one alpar@1218: // ///nodes of the shortest paths. alpar@1218: // ///It must meet the \ref concept::WriteMap "WriteMap" concept. alpar@1218: // /// alpar@1218: // typedef NullMap PredNodeMap; alpar@1218: // ///Instantiates a PredNodeMap. alpar@1125: alpar@1218: // ///This function instantiates a \ref PredNodeMap. alpar@1218: // ///\param G is the graph, to which alpar@1218: // ///we would like to define the \ref PredNodeMap alpar@1218: // static PredNodeMap *createPredNodeMap(const GR &G) alpar@1218: // { alpar@1218: // return new PredNodeMap(); alpar@1218: // } alpar@1119: alpar@1218: ///The type of the map that stores whether a nodes is processed. alpar@1119: alpar@1218: ///The type of the map that stores whether a nodes is processed. alpar@1119: ///It must meet the \ref concept::WriteMap "WriteMap" concept. alpar@1119: ///By default it is a NullMap. alpar@1218: ///\todo If it is set to a real map, alpar@1218: ///Dijkstra::processed() should read this. alpar@1119: ///\todo named parameter to set this type, function to read and write. alpar@1218: typedef NullMap ProcessedMap; alpar@1218: ///Instantiates a ProcessedMap. alpar@1119: alpar@1218: ///This function instantiates a \ref ProcessedMap. alpar@1156: ///\param G is the graph, to which alpar@1218: ///we would like to define the \ref ProcessedMap alpar@1218: static ProcessedMap *createProcessedMap(const GR &G) alpar@1119: { alpar@1218: return new ProcessedMap(); alpar@1119: } alpar@953: ///The type of the map that stores the dists of the nodes. alpar@953: hegyi@1124: ///The type of the map that stores the dists of the nodes. alpar@967: ///It must meet the \ref concept::WriteMap "WriteMap" concept. alpar@953: /// alpar@987: typedef typename Graph::template NodeMap DistMap; alpar@954: ///Instantiates a DistMap. alpar@953: hegyi@1123: ///This function instantiates a \ref DistMap. hegyi@1123: ///\param G is the graph, to which we would like to define the \ref DistMap alpar@954: static DistMap *createDistMap(const GR &G) alpar@953: { alpar@953: return new DistMap(G); alpar@953: } alpar@953: }; alpar@953: alpar@255: ///%Dijkstra algorithm class. alpar@1125: alpar@1151: /// \ingroup flowalgs alpar@255: ///This class provides an efficient implementation of %Dijkstra algorithm. alpar@255: ///The edge lengths are passed to the algorithm using a klao@959: ///\ref concept::ReadMap "ReadMap", alpar@255: ///so it is easy to change it to any kind of length. alpar@255: /// alpar@880: ///The type of the length is determined by the alpar@987: ///\ref concept::ReadMap::Value "Value" of the length map. alpar@255: /// alpar@255: ///It is also possible to change the underlying priority heap. alpar@255: /// alpar@1218: ///\param GR The graph type the algorithm runs on. The default value alpar@1218: ///is \ref ListGraph. The value of GR is not used directly by alpar@1218: ///Dijkstra, it is only passed to \ref DijkstraDefaultTraits. alpar@1218: ///\param LM This read-only EdgeMap determines the lengths of the alpar@1218: ///edges. It is read once for each edge, so the map may involve in alpar@1218: ///relatively time consuming process to compute the edge length if alpar@1218: ///it is necessary. The default map type is \ref alpar@1218: ///concept::StaticGraph::EdgeMap "Graph::EdgeMap". The value alpar@1218: ///of LM is not used directly by Dijkstra, it is only passed to \ref alpar@1218: ///DijkstraDefaultTraits. \param TR Traits class to set alpar@1218: ///various data types used by the algorithm. The default traits alpar@1218: ///class is \ref DijkstraDefaultTraits alpar@1218: ///"DijkstraDefaultTraits". See \ref alpar@1218: ///DijkstraDefaultTraits for the documentation of a Dijkstra traits alpar@1218: ///class. alpar@456: /// alpar@689: ///\author Jacint Szabo and Alpar Juttner alpar@1128: ///\todo A compare object would be nice. alpar@584: alpar@255: #ifdef DOXYGEN alpar@584: template alpar@255: #else alpar@953: template , alpar@953: typename TR=DijkstraDefaultTraits > alpar@255: #endif alpar@1116: class Dijkstra { alpar@255: public: alpar@1125: /** alpar@1125: * \brief \ref Exception for uninitialized parameters. alpar@1125: * alpar@1125: * This error represents problems in the initialization alpar@1125: * of the parameters of the algorithms. alpar@1125: */ alpar@1125: class UninitializedParameter : public lemon::UninitializedParameter { alpar@1125: public: alpar@1125: virtual const char* exceptionName() const { alpar@1218: return "lemon::Dijkstra::UninitializedParameter"; alpar@1125: } alpar@1125: }; alpar@1119: alpar@953: typedef TR Traits; alpar@584: ///The type of the underlying graph. alpar@954: typedef typename TR::Graph Graph; alpar@911: ///\e alpar@255: typedef typename Graph::Node Node; alpar@911: ///\e alpar@255: typedef typename Graph::NodeIt NodeIt; alpar@911: ///\e alpar@255: typedef typename Graph::Edge Edge; alpar@911: ///\e alpar@255: typedef typename Graph::OutEdgeIt OutEdgeIt; alpar@255: alpar@584: ///The type of the length of the edges. alpar@987: typedef typename TR::LengthMap::Value Value; alpar@693: ///The type of the map that stores the edge lengths. alpar@954: typedef typename TR::LengthMap LengthMap; alpar@693: ///\brief The type of the map that stores the last alpar@584: ///edges of the shortest paths. alpar@953: typedef typename TR::PredMap PredMap; alpar@1218: // ///\brief The type of the map that stores the last but one alpar@1218: // ///nodes of the shortest paths. alpar@1218: // typedef typename TR::PredNodeMap PredNodeMap; alpar@1218: ///The type of the map indicating if a node is processed. alpar@1218: typedef typename TR::ProcessedMap ProcessedMap; alpar@693: ///The type of the map that stores the dists of the nodes. alpar@953: typedef typename TR::DistMap DistMap; alpar@953: ///The heap type used by the dijkstra algorithm. alpar@953: typedef typename TR::Heap Heap; alpar@255: private: alpar@802: /// Pointer to the underlying graph. alpar@688: const Graph *G; alpar@802: /// Pointer to the length map alpar@954: const LengthMap *length; alpar@802: ///Pointer to the map of predecessors edges. alpar@1119: PredMap *_pred; alpar@1119: ///Indicates if \ref _pred is locally allocated (\c true) or not. alpar@1119: bool local_pred; alpar@1218: // ///Pointer to the map of predecessors nodes. alpar@1218: // PredNodeMap *_predNode; alpar@1218: // ///Indicates if \ref _predNode is locally allocated (\c true) or not. alpar@1218: // bool local_predNode; alpar@802: ///Pointer to the map of distances. alpar@1130: DistMap *_dist; alpar@1130: ///Indicates if \ref _dist is locally allocated (\c true) or not. alpar@1130: bool local_dist; alpar@1218: ///Pointer to the map of processed status of the nodes. alpar@1218: ProcessedMap *_processed; alpar@1218: ///Indicates if \ref _processed is locally allocated (\c true) or not. alpar@1218: bool local_processed; alpar@688: alpar@1218: // ///The source node of the last execution. alpar@1218: // Node source; alpar@774: alpar@1128: ///Creates the maps if necessary. alpar@688: alpar@694: ///\todo Error if \c G or are \c NULL. What about \c length? alpar@688: ///\todo Better memory allocation (instead of new). alpar@1128: void create_maps() alpar@688: { alpar@1119: if(!_pred) { alpar@1119: local_pred = true; alpar@1119: _pred = Traits::createPredMap(*G); alpar@688: } alpar@1218: // if(!_predNode) { alpar@1218: // local_predNode = true; alpar@1218: // _predNode = Traits::createPredNodeMap(*G); alpar@1218: // } alpar@1130: if(!_dist) { alpar@1130: local_dist = true; alpar@1130: _dist = Traits::createDistMap(*G); alpar@688: } alpar@1218: if(!_processed) { alpar@1218: local_processed = true; alpar@1218: _processed = Traits::createProcessedMap(*G); alpar@1119: } alpar@688: } alpar@255: alpar@255: public : alpar@1116: alpar@1128: ///\name Named template parameters alpar@1128: alpar@1128: ///@{ alpar@1128: alpar@953: template alpar@1116: struct DefPredMapTraits : public Traits { alpar@953: typedef T PredMap; alpar@953: static PredMap *createPredMap(const Graph &G) alpar@953: { alpar@1126: throw UninitializedParameter(); alpar@953: } alpar@953: }; alpar@954: ///\ref named-templ-param "Named parameter" for setting PredMap type alpar@954: alpar@954: ///\ref named-templ-param "Named parameter" for setting PredMap type alpar@1043: /// alpar@953: template alpar@1116: class DefPredMap : public Dijkstra< Graph, alpar@953: LengthMap, alpar@1116: DefPredMapTraits > { }; alpar@953: alpar@1218: // template alpar@1218: // struct DefPredNodeMapTraits : public Traits { alpar@1218: // typedef T PredNodeMap; alpar@1218: // static PredNodeMap *createPredNodeMap(const Graph &G) alpar@1218: // { alpar@1218: // throw UninitializedParameter(); alpar@1218: // } alpar@1218: // }; alpar@1218: // ///\ref named-templ-param "Named parameter" for setting PredNodeMap type alpar@954: alpar@1218: // ///\ref named-templ-param "Named parameter" for setting PredNodeMap type alpar@1218: // /// alpar@1218: // template alpar@1218: // class DefPredNodeMap : public Dijkstra< Graph, alpar@1218: // LengthMap, alpar@1218: // DefPredNodeMapTraits > { }; alpar@953: alpar@953: template alpar@1116: struct DefDistMapTraits : public Traits { alpar@953: typedef T DistMap; alpar@953: static DistMap *createDistMap(const Graph &G) alpar@953: { alpar@1126: throw UninitializedParameter(); alpar@953: } alpar@953: }; alpar@954: ///\ref named-templ-param "Named parameter" for setting DistMap type alpar@954: alpar@954: ///\ref named-templ-param "Named parameter" for setting DistMap type alpar@1043: /// alpar@953: template alpar@1116: class DefDistMap : public Dijkstra< Graph, alpar@953: LengthMap, alpar@1116: DefDistMapTraits > { }; alpar@953: alpar@1128: template alpar@1218: struct DefProcessedMapTraits : public Traits { alpar@1218: typedef T ProcessedMap; alpar@1218: static ProcessedMap *createProcessedMap(const Graph &G) alpar@1128: { alpar@1128: throw UninitializedParameter(); alpar@1128: } alpar@1128: }; alpar@1218: ///\ref named-templ-param "Named parameter" for setting ProcessedMap type alpar@1128: alpar@1218: ///\ref named-templ-param "Named parameter" for setting ProcessedMap type alpar@1128: /// alpar@1128: template alpar@1218: class DefProcessedMap : public Dijkstra< Graph, alpar@1128: LengthMap, alpar@1218: DefProcessedMapTraits > { }; alpar@1128: alpar@1218: struct DefGraphProcessedMapTraits : public Traits { alpar@1218: typedef typename Graph::template NodeMap ProcessedMap; alpar@1218: static ProcessedMap *createProcessedMap(const Graph &G) alpar@1128: { alpar@1218: return new ProcessedMap(G); alpar@1128: } alpar@1128: }; alpar@1128: ///\brief \ref named-templ-param "Named parameter" alpar@1218: ///for setting the ProcessedMap type to be Graph::NodeMap. alpar@1128: /// alpar@1128: ///\ref named-templ-param "Named parameter" alpar@1218: ///for setting the ProcessedMap type to be Graph::NodeMap. alpar@1128: ///If you don't set it explicitely, it will be automatically allocated. alpar@1128: template alpar@1218: class DefProcessedMapToBeDefaultMap : alpar@1128: public Dijkstra< Graph, alpar@1128: LengthMap, alpar@1218: DefGraphProcessedMapTraits> { }; alpar@1128: alpar@1128: ///@} alpar@1128: alpar@1128: alpar@1128: private: alpar@1128: typename Graph::template NodeMap _heap_map; alpar@1128: Heap _heap; alpar@1128: public: alpar@1128: alpar@802: ///Constructor. alpar@255: alpar@802: ///\param _G the graph the algorithm will run on. alpar@802: ///\param _length the length map used by the algorithm. alpar@954: Dijkstra(const Graph& _G, const LengthMap& _length) : alpar@688: G(&_G), length(&_length), alpar@1119: _pred(NULL), local_pred(false), alpar@1218: // _predNode(NULL), local_predNode(false), alpar@1130: _dist(NULL), local_dist(false), alpar@1218: _processed(NULL), local_processed(false), alpar@1128: _heap_map(*G,-1),_heap(_heap_map) alpar@688: { } alpar@688: alpar@802: ///Destructor. alpar@688: ~Dijkstra() alpar@688: { alpar@1119: if(local_pred) delete _pred; alpar@1218: // if(local_predNode) delete _predNode; alpar@1130: if(local_dist) delete _dist; alpar@1218: if(local_processed) delete _processed; alpar@688: } alpar@688: alpar@688: ///Sets the length map. alpar@688: alpar@688: ///Sets the length map. alpar@688: ///\return (*this) alpar@1116: Dijkstra &lengthMap(const LengthMap &m) alpar@688: { alpar@688: length = &m; alpar@688: return *this; alpar@688: } alpar@688: alpar@688: ///Sets the map storing the predecessor edges. alpar@688: alpar@688: ///Sets the map storing the predecessor edges. alpar@688: ///If you don't use this function before calling \ref run(), alpar@688: ///it will allocate one. The destuctor deallocates this alpar@688: ///automatically allocated map, of course. alpar@688: ///\return (*this) alpar@1116: Dijkstra &predMap(PredMap &m) alpar@688: { alpar@1119: if(local_pred) { alpar@1119: delete _pred; alpar@1119: local_pred=false; alpar@688: } alpar@1119: _pred = &m; alpar@688: return *this; alpar@688: } alpar@688: alpar@1218: // ///Sets the map storing the predecessor nodes. alpar@688: alpar@1218: // ///Sets the map storing the predecessor nodes. alpar@1218: // ///If you don't use this function before calling \ref run(), alpar@1218: // ///it will allocate one. The destuctor deallocates this alpar@1218: // ///automatically allocated map, of course. alpar@1218: // ///\return (*this) alpar@1218: // Dijkstra &predNodeMap(PredNodeMap &m) alpar@1218: // { alpar@1218: // if(local_predNode) { alpar@1218: // delete _predNode; alpar@1218: // local_predNode=false; alpar@1218: // } alpar@1218: // _predNode = &m; alpar@1218: // return *this; alpar@1218: // } alpar@688: alpar@688: ///Sets the map storing the distances calculated by the algorithm. alpar@688: alpar@688: ///Sets the map storing the distances calculated by the algorithm. alpar@688: ///If you don't use this function before calling \ref run(), alpar@688: ///it will allocate one. The destuctor deallocates this alpar@688: ///automatically allocated map, of course. alpar@688: ///\return (*this) alpar@1116: Dijkstra &distMap(DistMap &m) alpar@688: { alpar@1130: if(local_dist) { alpar@1130: delete _dist; alpar@1130: local_dist=false; alpar@688: } alpar@1130: _dist = &m; alpar@688: return *this; alpar@688: } alpar@694: alpar@1130: private: alpar@1130: void finalizeNodeData(Node v,Value dst) alpar@1130: { alpar@1218: _processed->set(v,true); alpar@1130: _dist->set(v, dst); alpar@1218: // if((*_pred)[v]!=INVALID) alpar@1218: // _predNode->set(v,G->source((*_pred)[v])); ///\todo What to do? alpar@1130: } alpar@1130: alpar@1130: public: alpar@1218: ///\name Execution control alpar@1128: ///The simplest way to execute the algorithm is to use alpar@1156: ///one of the member functions called \c run(...). alpar@1128: ///\n alpar@1218: ///If you need more control on the execution, alpar@1128: ///first you must call \ref init(), then you can add several source nodes alpar@1218: ///with \ref addSource(). alpar@1218: ///Finally \ref start() will perform the actual path alpar@1128: ///computation. alpar@1128: alpar@1128: ///@{ alpar@1128: alpar@1128: ///Initializes the internal data structures. alpar@1128: alpar@1128: ///Initializes the internal data structures. alpar@1128: /// alpar@1128: ///\todo _heap_map's type could also be in the traits class. alpar@1128: void init() alpar@1128: { alpar@1128: create_maps(); alpar@774: alpar@774: for ( NodeIt u(*G) ; u!=INVALID ; ++u ) { alpar@1119: _pred->set(u,INVALID); alpar@1218: // _predNode->set(u,INVALID); alpar@1218: _processed->set(u,false); alpar@1128: _heap_map.set(u,Heap::PRE_HEAP); alpar@694: } alpar@1128: } alpar@1128: alpar@1128: ///Adds a new source node. alpar@1128: alpar@1155: ///Adds a new source node to the priority heap. alpar@1128: /// alpar@1128: ///The optional second parameter is the initial distance of the node. alpar@1128: /// alpar@1155: ///It checks if the node has already been added to the heap and alpar@1155: ///It is pushed to the heap only if either it was not in the heap alpar@1155: ///or the shortest path found till then is longer then \c dst. alpar@1128: void addSource(Node s,Value dst=0) alpar@1128: { alpar@1218: // source = s; alpar@1128: if(_heap.state(s) != Heap::IN_HEAP) _heap.push(s,dst); alpar@1155: else if(_heap[s]set(s,INVALID); alpar@1155: } alpar@1128: } alpar@1128: alpar@1155: ///Processes the next node in the priority heap alpar@1155: alpar@1155: ///Processes the next node in the priority heap. alpar@1155: /// alpar@1155: ///\warning The priority heap must not be empty! alpar@1151: void processNextNode() alpar@1128: { alpar@1128: Node v=_heap.top(); alpar@1128: Value oldvalue=_heap[v]; alpar@1128: _heap.pop(); alpar@1130: finalizeNodeData(v,oldvalue); alpar@694: alpar@1128: for(OutEdgeIt e(*G,v); e!=INVALID; ++e) { alpar@1128: Node w=G->target(e); alpar@1128: switch(_heap.state(w)) { alpar@1128: case Heap::PRE_HEAP: alpar@1128: _heap.push(w,oldvalue+(*length)[e]); alpar@1128: _pred->set(w,e); alpar@1130: // _predNode->set(w,v); alpar@1128: break; alpar@1128: case Heap::IN_HEAP: alpar@1128: if ( oldvalue+(*length)[e] < _heap[w] ) { alpar@1128: _heap.decrease(w, oldvalue+(*length)[e]); alpar@1119: _pred->set(w,e); alpar@1130: // _predNode->set(w,v); alpar@694: } alpar@1128: break; alpar@1128: case Heap::POST_HEAP: alpar@1128: break; alpar@694: } alpar@694: } alpar@694: } alpar@1128: alpar@1218: ///\brief Returns \c false if there are nodes alpar@1218: ///to be processed in the priority heap alpar@1155: /// alpar@1218: ///Returns \c false if there are nodes alpar@1218: ///to be processed in the priority heap alpar@1218: bool emptyQueue() { return _heap.empty(); } alpar@1155: ///Returns the number of the nodes to be processed in the priority heap alpar@1155: alpar@1155: ///Returns the number of the nodes to be processed in the priority heap alpar@1155: /// alpar@1218: int queueSize() { return _heap.size(); } alpar@1155: alpar@1130: ///Executes the algorithm. alpar@1128: alpar@1130: ///Executes the algorithm. alpar@1128: /// alpar@1130: ///\pre init() must be called and at least one node should be added alpar@1130: ///with addSource() before using this function. alpar@1128: /// alpar@1128: ///This method runs the %Dijkstra algorithm from the root node(s) alpar@1128: ///in order to alpar@1128: ///compute the alpar@1128: ///shortest path to each node. The algorithm computes alpar@1128: ///- The shortest path tree. alpar@1128: ///- The distance of each node from the root(s). alpar@1128: /// alpar@1128: void start() alpar@1128: { alpar@1151: while ( !_heap.empty() ) processNextNode(); alpar@1128: } alpar@255: alpar@1130: ///Executes the algorithm until \c dest is reached. alpar@1128: alpar@1130: ///Executes the algorithm until \c dest is reached. alpar@1128: /// alpar@1130: ///\pre init() must be called and at least one node should be added alpar@1130: ///with addSource() before using this function. alpar@1128: /// alpar@1128: ///This method runs the %Dijkstra algorithm from the root node(s) alpar@1128: ///in order to alpar@1128: ///compute the alpar@1128: ///shortest path to \c dest. The algorithm computes alpar@1128: ///- The shortest path to \c dest. alpar@1128: ///- The distance of \c dest from the root(s). alpar@1128: /// alpar@1128: void start(Node dest) alpar@1128: { alpar@1151: while ( !_heap.empty() && _heap.top()!=dest ) processNextNode(); alpar@1130: if ( _heap.top()==dest ) finalizeNodeData(_heap.top()); alpar@1130: } alpar@1130: alpar@1130: ///Executes the algorithm until a condition is met. alpar@1130: alpar@1130: ///Executes the algorithm until a condition is met. alpar@1130: /// alpar@1130: ///\pre init() must be called and at least one node should be added alpar@1130: ///with addSource() before using this function. alpar@1130: /// alpar@1130: ///\param nm must be a bool (or convertible) node map. The algorithm alpar@1130: ///will stop when it reaches a node \c v with nm[v]==true. alpar@1130: template alpar@1130: void start(const NM &nm) alpar@1130: { deba@1193: while ( !_heap.empty() && !nm[_heap.top()] ) processNextNode(); alpar@1130: if ( !_heap.empty() ) finalizeNodeData(_heap.top()); alpar@1128: } alpar@1128: alpar@1128: ///Runs %Dijkstra algorithm from node \c s. alpar@1128: alpar@1128: ///This method runs the %Dijkstra algorithm from a root node \c s alpar@1128: ///in order to alpar@1128: ///compute the alpar@1128: ///shortest path to each node. The algorithm computes alpar@1128: ///- The shortest path tree. alpar@1128: ///- The distance of each node from the root. alpar@1128: /// alpar@1128: ///\note d.run(s) is just a shortcut of the following code. alpar@1128: ///\code alpar@1128: /// d.init(); alpar@1128: /// d.addSource(s); alpar@1128: /// d.start(); alpar@1128: ///\endcode alpar@1128: void run(Node s) { alpar@1128: init(); alpar@1128: addSource(s); alpar@1128: start(); alpar@1128: } alpar@1128: alpar@1130: ///Finds the shortest path between \c s and \c t. alpar@1130: alpar@1130: ///Finds the shortest path between \c s and \c t. alpar@1130: /// alpar@1130: ///\return The length of the shortest s---t path if there exists one, alpar@1130: ///0 otherwise. alpar@1130: ///\note Apart from the return value, d.run(s) is alpar@1130: ///just a shortcut of the following code. alpar@1130: ///\code alpar@1130: /// d.init(); alpar@1130: /// d.addSource(s); alpar@1130: /// d.start(t); alpar@1130: ///\endcode alpar@1130: Value run(Node s,Node t) { alpar@1130: init(); alpar@1130: addSource(s); alpar@1130: start(t); alpar@1130: return (*_pred)[t]==INVALID?0:(*_dist)[t]; alpar@1130: } alpar@1130: alpar@1128: ///@} alpar@1128: alpar@1128: ///\name Query Functions alpar@1128: ///The result of the %Dijkstra algorithm can be obtained using these alpar@1128: ///functions.\n alpar@1128: ///Before the use of these functions, alpar@1128: ///either run() or start() must be called. alpar@1128: alpar@1128: ///@{ alpar@1128: jacint@385: ///The distance of a node from the root. alpar@255: jacint@385: ///Returns the distance of a node from the root. alpar@255: ///\pre \ref run() must be called before using this function. jacint@385: ///\warning If node \c v in unreachable from the root the return value alpar@255: ///of this funcion is undefined. alpar@1130: Value dist(Node v) const { return (*_dist)[v]; } jacint@373: alpar@584: ///Returns the 'previous edge' of the shortest path tree. alpar@255: alpar@584: ///For a node \c v it returns the 'previous edge' of the shortest path tree, alpar@785: ///i.e. it returns the last edge of a shortest path from the root to \c alpar@688: ///v. It is \ref INVALID alpar@688: ///if \c v is unreachable from the root or if \c v=s. The jacint@385: ///shortest path tree used here is equal to the shortest path tree used in jacint@385: ///\ref predNode(Node v). \pre \ref run() must be called before using jacint@385: ///this function. alpar@780: ///\todo predEdge could be a better name. alpar@1119: Edge pred(Node v) const { return (*_pred)[v]; } jacint@373: alpar@584: ///Returns the 'previous node' of the shortest path tree. alpar@255: alpar@584: ///For a node \c v it returns the 'previous node' of the shortest path tree, jacint@385: ///i.e. it returns the last but one node from a shortest path from the jacint@385: ///root to \c /v. It is INVALID if \c v is unreachable from the root or if jacint@385: ///\c v=s. The shortest path tree used here is equal to the shortest path jacint@385: ///tree used in \ref pred(Node v). \pre \ref run() must be called before jacint@385: ///using this function. alpar@1130: Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID: alpar@1130: G->source((*_pred)[v]); } alpar@255: alpar@255: ///Returns a reference to the NodeMap of distances. alpar@255: jacint@385: ///Returns a reference to the NodeMap of distances. \pre \ref run() must jacint@385: ///be called before using this function. alpar@1130: const DistMap &distMap() const { return *_dist;} jacint@385: alpar@255: ///Returns a reference to the shortest path tree map. alpar@255: alpar@255: ///Returns a reference to the NodeMap of the edges of the alpar@255: ///shortest path tree. alpar@255: ///\pre \ref run() must be called before using this function. alpar@1119: const PredMap &predMap() const { return *_pred;} jacint@385: alpar@1218: // ///Returns a reference to the map of nodes of shortest paths. alpar@255: alpar@1218: // ///Returns a reference to the NodeMap of the last but one nodes of the alpar@1218: // ///shortest path tree. alpar@1218: // ///\pre \ref run() must be called before using this function. alpar@1218: // const PredNodeMap &predNodeMap() const { return *_predNode;} alpar@255: jacint@385: ///Checks if a node is reachable from the root. alpar@255: jacint@385: ///Returns \c true if \c v is reachable from the root. alpar@1218: ///\warning The source nodes are inditated as unreached. alpar@255: ///\pre \ref run() must be called before using this function. jacint@385: /// alpar@1218: bool reached(Node v) { return _heap_map[v]!=Heap::PRE_HEAP; } alpar@255: alpar@1128: ///@} alpar@255: }; alpar@953: alpar@1218: alpar@1218: alpar@1218: alpar@1218: alpar@1218: ///Default traits class of Dijkstra function. alpar@1218: alpar@1218: ///Default traits class of Dijkstra function. alpar@1218: ///\param GR Graph type. alpar@1218: ///\param LM Type of length map. alpar@1218: template alpar@1218: struct DijkstraWizardDefaultTraits alpar@1218: { alpar@1218: ///The graph type the algorithm runs on. alpar@1218: typedef GR Graph; alpar@1218: ///The type of the map that stores the edge lengths. alpar@1218: alpar@1218: ///The type of the map that stores the edge lengths. alpar@1218: ///It must meet the \ref concept::ReadMap "ReadMap" concept. alpar@1218: typedef LM LengthMap; alpar@1218: //The type of the length of the edges. alpar@1218: typedef typename LM::Value Value; alpar@1218: ///The heap type used by Dijkstra algorithm. alpar@1218: alpar@1218: ///The heap type used by Dijkstra algorithm. alpar@1218: /// alpar@1218: ///\sa BinHeap alpar@1218: ///\sa Dijkstra alpar@1218: typedef BinHeap, alpar@1218: std::less > Heap; alpar@1218: alpar@1218: ///\brief The type of the map that stores the last alpar@1218: ///edges of the shortest paths. alpar@1218: /// alpar@1218: ///The type of the map that stores the last alpar@1218: ///edges of the shortest paths. alpar@1218: ///It must meet the \ref concept::WriteMap "WriteMap" concept. alpar@1218: /// alpar@1218: typedef NullMap PredMap; alpar@1218: ///Instantiates a PredMap. alpar@1218: alpar@1218: ///This function instantiates a \ref PredMap. alpar@1218: ///\param G is the graph, to which we would like to define the PredMap. alpar@1218: ///\todo The graph alone may be insufficient for the initialization alpar@1218: static PredMap *createPredMap(const GR &G) alpar@1218: { alpar@1218: return new PredMap(); alpar@1218: } alpar@1218: ///The type of the map that stores whether a nodes is processed. alpar@1218: alpar@1218: ///The type of the map that stores whether a nodes is processed. alpar@1218: ///It must meet the \ref concept::WriteMap "WriteMap" concept. alpar@1218: ///By default it is a NullMap. alpar@1218: ///\todo If it is set to a real map, alpar@1218: ///Dijkstra::processed() should read this. alpar@1218: ///\todo named parameter to set this type, function to read and write. alpar@1218: typedef NullMap ProcessedMap; alpar@1218: ///Instantiates a ProcessedMap. alpar@1218: alpar@1218: ///This function instantiates a \ref ProcessedMap. alpar@1218: ///\param G is the graph, to which alpar@1218: ///we would like to define the \ref ProcessedMap alpar@1218: static ProcessedMap *createProcessedMap(const GR &G) alpar@1218: { alpar@1218: return new ProcessedMap(); alpar@1218: } alpar@1218: ///The type of the map that stores the dists of the nodes. alpar@1218: alpar@1218: ///The type of the map that stores the dists of the nodes. alpar@1218: ///It must meet the \ref concept::WriteMap "WriteMap" concept. alpar@1218: /// alpar@1218: typedef NullMap DistMap; alpar@1218: ///Instantiates a DistMap. alpar@1218: alpar@1218: ///This function instantiates a \ref DistMap. alpar@1218: ///\param G is the graph, to which we would like to define the \ref DistMap alpar@1218: static DistMap *createDistMap(const GR &G) alpar@1218: { alpar@1218: return new DistMap(); alpar@1218: } alpar@1218: }; alpar@1218: hegyi@1123: /// Default traits used by \ref DijkstraWizard hegyi@1123: alpar@1151: /// To make it easier to use Dijkstra algorithm alpar@1151: ///we have created a wizard class. alpar@1151: /// This \ref DijkstraWizard class needs default traits, alpar@1151: ///as well as the \ref Dijkstra class. hegyi@1123: /// The \ref DijkstraWizardBase is a class to be the default traits of the hegyi@1123: /// \ref DijkstraWizard class. alpar@1220: /// \todo More named parameters are required... alpar@1116: template alpar@1218: class DijkstraWizardBase : public DijkstraWizardDefaultTraits alpar@1116: { alpar@1116: alpar@1218: typedef DijkstraWizardDefaultTraits Base; alpar@1116: protected: alpar@1201: /// Type of the nodes in the graph. alpar@1201: typedef typename Base::Graph::Node Node; alpar@1201: alpar@1116: /// Pointer to the underlying graph. alpar@1116: void *_g; alpar@1116: /// Pointer to the length map alpar@1116: void *_length; alpar@1116: ///Pointer to the map of predecessors edges. alpar@1116: void *_pred; alpar@1218: // ///Pointer to the map of predecessors nodes. alpar@1218: // void *_predNode; alpar@1116: ///Pointer to the map of distances. alpar@1116: void *_dist; alpar@1116: ///Pointer to the source node. alpar@1201: Node _source; alpar@1116: alpar@1116: public: hegyi@1123: /// Constructor. hegyi@1123: hegyi@1123: /// This constructor does not require parameters, therefore it initiates hegyi@1123: /// all of the attributes to default values (0, INVALID). alpar@1218: DijkstraWizardBase() : _g(0), _length(0), _pred(0), alpar@1218: // _predNode(0), alpar@1218: _dist(0), _source(INVALID) {} alpar@1116: hegyi@1123: /// Constructor. hegyi@1123: alpar@1156: /// This constructor requires some parameters, alpar@1156: /// listed in the parameters list. hegyi@1123: /// Others are initiated to 0. hegyi@1123: /// \param g is the initial value of \ref _g hegyi@1123: /// \param l is the initial value of \ref _length hegyi@1123: /// \param s is the initial value of \ref _source alpar@1116: DijkstraWizardBase(const GR &g,const LM &l, Node s=INVALID) : alpar@1218: _g((void *)&g), _length((void *)&l), _pred(0), alpar@1218: // _predNode(0), alpar@1218: _dist(0), _source(s) {} alpar@1116: alpar@1116: }; alpar@1116: hegyi@1123: /// A class to make easier the usage of Dijkstra algorithm alpar@953: hegyi@1123: /// This class is created to make it easier to use Dijkstra algorithm. hegyi@1123: /// It uses the functions and features of the plain \ref Dijkstra, alpar@1151: /// but it is much simpler to use it. alpar@953: /// hegyi@1123: /// Simplicity means that the way to change the types defined hegyi@1123: /// in the traits class is based on functions that returns the new class alpar@1151: /// and not on templatable built-in classes. alpar@1151: /// When using the plain \ref Dijkstra alpar@1151: /// the new class with the modified type comes from alpar@1151: /// the original class by using the :: alpar@1151: /// operator. In the case of \ref DijkstraWizard only alpar@1151: /// a function have to be called and it will hegyi@1123: /// return the needed class. hegyi@1123: /// hegyi@1123: /// It does not have own \ref run method. When its \ref run method is called hegyi@1123: /// it initiates a plain \ref Dijkstra class, and calls the \ref Dijkstra::run hegyi@1123: /// method of it. alpar@953: template alpar@1116: class DijkstraWizard : public TR alpar@953: { alpar@1116: typedef TR Base; alpar@953: hegyi@1123: ///The type of the underlying graph. alpar@953: typedef typename TR::Graph Graph; alpar@1119: //\e alpar@953: typedef typename Graph::Node Node; alpar@1119: //\e alpar@953: typedef typename Graph::NodeIt NodeIt; alpar@1119: //\e alpar@953: typedef typename Graph::Edge Edge; alpar@1119: //\e alpar@953: typedef typename Graph::OutEdgeIt OutEdgeIt; alpar@953: hegyi@1123: ///The type of the map that stores the edge lengths. alpar@953: typedef typename TR::LengthMap LengthMap; hegyi@1123: ///The type of the length of the edges. alpar@987: typedef typename LengthMap::Value Value; hegyi@1123: ///\brief The type of the map that stores the last hegyi@1123: ///edges of the shortest paths. alpar@953: typedef typename TR::PredMap PredMap; alpar@1218: // ///\brief The type of the map that stores the last but one alpar@1218: // ///nodes of the shortest paths. alpar@1218: // typedef typename TR::PredNodeMap PredNodeMap; hegyi@1123: ///The type of the map that stores the dists of the nodes. alpar@953: typedef typename TR::DistMap DistMap; alpar@953: hegyi@1123: ///The heap type used by the dijkstra algorithm. alpar@953: typedef typename TR::Heap Heap; alpar@1116: public: hegyi@1123: /// Constructor. alpar@1116: DijkstraWizard() : TR() {} alpar@953: hegyi@1123: /// Constructor that requires parameters. hegyi@1124: hegyi@1124: /// Constructor that requires parameters. hegyi@1123: /// These parameters will be the default values for the traits class. alpar@1116: DijkstraWizard(const Graph &g,const LengthMap &l, Node s=INVALID) : alpar@1116: TR(g,l,s) {} alpar@953: hegyi@1123: ///Copy constructor alpar@1116: DijkstraWizard(const TR &b) : TR(b) {} alpar@953: alpar@1116: ~DijkstraWizard() {} alpar@1116: hegyi@1123: ///Runs Dijkstra algorithm from a given node. hegyi@1123: hegyi@1123: ///Runs Dijkstra algorithm from a given node. hegyi@1123: ///The node can be given by the \ref source function. alpar@1116: void run() alpar@953: { alpar@1201: if(Base::_source==INVALID) throw UninitializedParameter(); deba@1193: Dijkstra deba@1193: Dij(*(Graph*)Base::_g,*(LengthMap*)Base::_length); deba@1193: if(Base::_pred) Dij.predMap(*(PredMap*)Base::_pred); alpar@1218: // if(Base::_predNode) Dij.predNodeMap(*(PredNodeMap*)Base::_predNode); deba@1193: if(Base::_dist) Dij.distMap(*(DistMap*)Base::_dist); alpar@1201: Dij.run(Base::_source); alpar@1116: } alpar@1116: hegyi@1124: ///Runs Dijkstra algorithm from the given node. hegyi@1123: hegyi@1124: ///Runs Dijkstra algorithm from the given node. hegyi@1123: ///\param s is the given source. alpar@1116: void run(Node s) alpar@1116: { alpar@1201: Base::_source=s; alpar@1116: run(); alpar@953: } alpar@953: alpar@953: template alpar@1116: struct DefPredMapBase : public Base { alpar@1116: typedef T PredMap; alpar@1117: static PredMap *createPredMap(const Graph &G) { return 0; }; alpar@1117: DefPredMapBase(const Base &b) : Base(b) {} alpar@1116: }; alpar@953: alpar@1156: ///\brief \ref named-templ-param "Named parameter" alpar@1156: ///function for setting PredMap type alpar@1156: /// alpar@1156: /// \ref named-templ-param "Named parameter" alpar@1156: ///function for setting PredMap type hegyi@1124: /// alpar@953: template alpar@1116: DijkstraWizard > predMap(const T &t) alpar@953: { deba@1193: Base::_pred=(void *)&t; alpar@1116: return DijkstraWizard >(*this); alpar@953: } alpar@953: alpar@1116: alpar@1218: // template alpar@1218: // struct DefPredNodeMapBase : public Base { alpar@1218: // typedef T PredNodeMap; alpar@1218: // static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; }; alpar@1218: // DefPredNodeMapBase(const Base &b) : Base(b) {} alpar@1218: // }; alpar@1116: alpar@1218: // ///\brief \ref named-templ-param "Named parameter" alpar@1218: // ///function for setting PredNodeMap type alpar@1218: // /// alpar@1218: // /// \ref named-templ-param "Named parameter" alpar@1218: // ///function for setting PredNodeMap type alpar@1218: // /// alpar@1218: // template alpar@1218: // DijkstraWizard > predNodeMap(const T &t) alpar@1218: // { alpar@1218: // Base::_predNode=(void *)&t; alpar@1218: // return DijkstraWizard >(*this); alpar@1218: // } alpar@1116: alpar@1116: template alpar@1116: struct DefDistMapBase : public Base { alpar@1116: typedef T DistMap; alpar@1117: static DistMap *createDistMap(const Graph &G) { return 0; }; alpar@1117: DefDistMapBase(const Base &b) : Base(b) {} alpar@1116: }; alpar@953: alpar@1156: ///\brief \ref named-templ-param "Named parameter" alpar@1156: ///function for setting DistMap type alpar@1156: /// alpar@1156: /// \ref named-templ-param "Named parameter" alpar@1156: ///function for setting DistMap type hegyi@1124: /// alpar@953: template alpar@1116: DijkstraWizard > distMap(const T &t) alpar@953: { deba@1193: Base::_dist=(void *)&t; alpar@1116: return DijkstraWizard >(*this); alpar@953: } alpar@1117: hegyi@1123: /// Sets the source node, from which the Dijkstra algorithm runs. hegyi@1123: hegyi@1123: /// Sets the source node, from which the Dijkstra algorithm runs. hegyi@1123: /// \param s is the source node. alpar@1117: DijkstraWizard &source(Node s) alpar@953: { alpar@1201: Base::_source=s; alpar@953: return *this; alpar@953: } alpar@953: alpar@953: }; alpar@255: alpar@1218: ///Function type interface for Dijkstra algorithm. alpar@953: alpar@1151: /// \ingroup flowalgs alpar@1218: ///Function type interface for Dijkstra algorithm. alpar@953: /// alpar@1218: ///This function also has several alpar@1218: ///\ref named-templ-func-param "named parameters", alpar@1218: ///they are declared as the members of class \ref DijkstraWizard. alpar@1218: ///The following alpar@1218: ///example shows how to use these parameters. alpar@1218: ///\code alpar@1218: /// dijkstra(g,length,source).predMap(preds).run(); alpar@1218: ///\endcode alpar@1218: ///\warning Don't forget to put the \ref DijkstraWizard::run() "run()" alpar@1218: ///to the end of the parameter list. alpar@1218: ///\sa DijkstraWizard alpar@1218: ///\sa Dijkstra alpar@953: template alpar@1116: DijkstraWizard > alpar@1116: dijkstra(const GR &g,const LM &l,typename GR::Node s=INVALID) alpar@953: { alpar@1116: return DijkstraWizard >(g,l,s); alpar@953: } alpar@953: alpar@921: } //END OF NAMESPACE LEMON alpar@255: alpar@255: #endif alpar@255: