alpar@906: /* -*- C++ -*- alpar@921: * src/lemon/dijkstra.h - Part of LEMON, a generic C++ optimization library alpar@906: * alpar@906: * Copyright (C) 2004 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@758: /// \addtogroup flowalgs alpar@430: /// @{ alpar@430: 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@953: ///\brief The type of the map that stores the last but one alpar@953: ///nodes of the shortest paths. alpar@953: /// hegyi@1124: ///The type of the map that stores the last but one hegyi@1124: ///nodes of the shortest paths. alpar@967: ///It must meet the \ref concept::WriteMap "WriteMap" concept. alpar@953: /// alpar@1130: typedef NullMap PredNodeMap; alpar@954: ///Instantiates a PredNodeMap. alpar@1125: hegyi@1123: ///This function instantiates a \ref PredNodeMap. hegyi@1123: ///\param G is the graph, to which we would like to define the \ref PredNodeMap alpar@954: static PredNodeMap *createPredNodeMap(const GR &G) alpar@953: { alpar@1130: return new PredNodeMap(); alpar@953: } alpar@1119: alpar@1119: ///The type of the map that stores whether a nodes is reached. alpar@1119: hegyi@1124: ///The type of the map that stores whether a nodes is reached. alpar@1119: ///It must meet the \ref concept::WriteMap "WriteMap" concept. alpar@1119: ///By default it is a NullMap. alpar@1119: ///\todo If it is set to a real map, Dijkstra::reached() should read this. alpar@1119: ///\todo named parameter to set this type, function to read and write. alpar@1119: typedef NullMap ReachedMap; alpar@1119: ///Instantiates a ReachedMap. alpar@1119: hegyi@1123: ///This function instantiates a \ref ReachedMap. hegyi@1123: ///\param G is the graph, to which we would like to define the \ref ReachedMap alpar@1119: static ReachedMap *createReachedMap(const GR &G) alpar@1119: { alpar@1119: return new ReachedMap(); 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@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@953: ///\param GR The graph type the algorithm runs on. The default value is alpar@955: ///\ref ListGraph. The value of GR is not used directly by Dijkstra, it alpar@954: ///is only passed to \ref DijkstraDefaultTraits. alpar@584: ///\param LM This read-only jacint@385: ///EdgeMap jacint@385: ///determines the jacint@385: ///lengths of the edges. It is read once for each edge, so the map jacint@385: ///may involve in relatively time consuming process to compute the edge jacint@385: ///length if it is necessary. The default map type is klao@959: ///\ref concept::StaticGraph::EdgeMap "Graph::EdgeMap". alpar@955: ///The value of LM is not used directly by Dijkstra, it alpar@954: ///is only passed to \ref DijkstraDefaultTraits. alpar@954: ///\param TR Traits class to set various data types used by the algorithm. alpar@954: ///The default traits class is alpar@955: ///\ref DijkstraDefaultTraits "DijkstraDefaultTraits". alpar@954: ///See \ref DijkstraDefaultTraits for the documentation of alpar@954: ///a Dijkstra traits 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@1125: return "lemon::Dijsktra::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@693: ///\brief The type of the map that stores the last but one alpar@584: ///nodes of the shortest paths. alpar@953: typedef typename TR::PredNodeMap PredNodeMap; alpar@1119: ///The type of the map indicating if a node is reached. alpar@1119: typedef typename TR::ReachedMap ReachedMap; 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@802: ///Pointer to the map of predecessors nodes. alpar@1130: PredNodeMap *_predNode; alpar@1130: ///Indicates if \ref _predNode is locally allocated (\c true) or not. alpar@1130: 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@1119: ///Pointer to the map of reached status of the nodes. alpar@1119: ReachedMap *_reached; alpar@1119: ///Indicates if \ref _reached is locally allocated (\c true) or not. alpar@1119: bool local_reached; alpar@688: alpar@802: ///The source node of the last execution. alpar@774: 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@1130: if(!_predNode) { alpar@1130: local_predNode = true; alpar@1130: _predNode = Traits::createPredNodeMap(*G); alpar@688: } alpar@1130: if(!_dist) { alpar@1130: local_dist = true; alpar@1130: _dist = Traits::createDistMap(*G); alpar@688: } alpar@1119: if(!_reached) { alpar@1119: local_reached = true; alpar@1119: _reached = Traits::createReachedMap(*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@953: template alpar@1116: struct DefPredNodeMapTraits : public Traits { alpar@953: typedef T PredNodeMap; alpar@953: static PredNodeMap *createPredNodeMap(const Graph &G) alpar@953: { alpar@1126: throw UninitializedParameter(); alpar@953: } alpar@953: }; alpar@954: ///\ref named-templ-param "Named parameter" for setting PredNodeMap type alpar@954: alpar@954: ///\ref named-templ-param "Named parameter" for setting PredNodeMap type alpar@1043: /// alpar@953: template alpar@1116: class DefPredNodeMap : public Dijkstra< Graph, alpar@953: LengthMap, alpar@1116: 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@1128: struct DefReachedMapTraits : public Traits { alpar@1128: typedef T ReachedMap; alpar@1128: static ReachedMap *createReachedMap(const Graph &G) alpar@1128: { alpar@1128: throw UninitializedParameter(); alpar@1128: } alpar@1128: }; alpar@1128: ///\ref named-templ-param "Named parameter" for setting ReachedMap type alpar@1128: alpar@1128: ///\ref named-templ-param "Named parameter" for setting ReachedMap type alpar@1128: /// alpar@1128: template alpar@1128: class DefReachedMap : public Dijkstra< Graph, alpar@1128: LengthMap, alpar@1128: DefReachedMapTraits > { }; alpar@1128: alpar@1128: struct DefGraphReachedMapTraits : public Traits { alpar@1128: typedef typename Graph::NodeMap ReachedMap; alpar@1128: static ReachedMap *createReachedMap(const Graph &G) alpar@1128: { alpar@1128: return new ReachedMap(G); alpar@1128: } alpar@1128: }; alpar@1128: ///\brief \ref named-templ-param "Named parameter" alpar@1128: ///for setting the ReachedMap type to be Graph::NodeMap. alpar@1128: /// alpar@1128: ///\ref named-templ-param "Named parameter" alpar@1128: ///for setting the ReachedMap type to be Graph::NodeMap. alpar@1128: ///If you don't set it explicitely, it will be automatically allocated. alpar@1128: template alpar@1128: class DefReachedMapToBeDefaultMap : alpar@1128: public Dijkstra< Graph, alpar@1128: LengthMap, alpar@1128: DefGraphReachedMapTraits> { }; 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@1130: _predNode(NULL), local_predNode(false), alpar@1130: _dist(NULL), local_dist(false), alpar@1128: _reached(NULL), local_reached(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@1130: if(local_predNode) delete _predNode; alpar@1130: if(local_dist) delete _dist; alpar@1119: if(local_reached) delete _reached; 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@688: ///Sets the map storing the predecessor nodes. alpar@688: alpar@688: ///Sets the map storing the predecessor nodes. 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 &predNodeMap(PredNodeMap &m) alpar@688: { alpar@1130: if(local_predNode) { alpar@1130: delete _predNode; alpar@1130: local_predNode=false; alpar@688: } alpar@1130: _predNode = &m; alpar@688: return *this; alpar@688: } 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@1130: _reached->set(v,true); alpar@1130: _dist->set(v, dst); alpar@1130: _predNode->set(v,G->source((*_pred)[v])); alpar@1130: } alpar@1130: alpar@1130: public: alpar@1128: ///\name Excetution control alpar@1128: ///The simplest way to execute the algorithm is to use alpar@1128: ///\ref run(). alpar@1128: ///\n alpar@1128: ///It you need more control on the execution, alpar@1128: ///first you must call \ref init(), then you can add several source nodes alpar@1128: ///with \ref addSource(). 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@1130: _predNode->set(u,INVALID); alpar@1119: ///\todo *_reached is not set to 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@1128: ///Adds a new source node the the priority heap. alpar@1128: ///It checks if the node has already been added to the heap. alpar@1128: /// alpar@1128: ///The optional second parameter is the initial distance of the node. alpar@1128: /// alpar@1128: ///\todo Do we really want to check it? alpar@1128: void addSource(Node s,Value dst=0) alpar@1128: { alpar@1128: source = s; alpar@1128: if(_heap.state(s) != Heap::IN_HEAP) _heap.push(s,dst); alpar@1128: } alpar@1128: alpar@1128: void processNode() 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@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@1128: while ( !_heap.empty() ) processNode(); 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@1130: while ( !_heap.empty() && _heap.top()!=dest ) processNode(); 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: { alpar@1130: while ( !_heap.empty() && !mn[_heap.top()] ) processNode(); 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: jacint@385: ///Returns a reference to the map of nodes of shortest paths. alpar@255: alpar@255: ///Returns a reference to the NodeMap of the last but one nodes of the jacint@385: ///shortest path tree. alpar@255: ///\pre \ref run() must be called before using this function. alpar@1130: 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@1128: ///\warning If the algorithm is started from multiple nodes, alpar@1128: ///this function may give false result for the source nodes. alpar@255: ///\pre \ref run() must be called before using this function. jacint@385: /// alpar@1119: bool reached(Node v) { return v==source || (*_pred)[v]!=INVALID; } alpar@255: alpar@1128: ///@} alpar@255: }; alpar@953: hegyi@1123: /// Default traits used by \ref DijkstraWizard hegyi@1123: hegyi@1124: /// To make it easier to use Dijkstra algorithm we have created a wizard class. hegyi@1124: /// This \ref DijkstraWizard class needs default traits, 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@1116: template alpar@1116: class DijkstraWizardBase : public DijkstraDefaultTraits alpar@1116: { alpar@1116: alpar@1116: typedef DijkstraDefaultTraits Base; alpar@1116: protected: 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@1116: ///Pointer to the map of predecessors nodes. alpar@1116: void *_predNode; alpar@1116: ///Pointer to the map of distances. alpar@1116: void *_dist; alpar@1116: ///Pointer to the source node. alpar@1116: void *_source; alpar@1116: hegyi@1123: /// Type of the nodes in the graph. alpar@1116: typedef typename Base::Graph::Node Node; 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@1116: DijkstraWizardBase() : _g(0), _length(0), _pred(0), _predNode(0), alpar@1116: _dist(0), _source(INVALID) {} alpar@1116: hegyi@1123: /// Constructor. hegyi@1123: hegyi@1123: /// This constructor requires some parameters, 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@1116: _g((void *)&g), _length((void *)&l), _pred(0), _predNode(0), alpar@1116: _dist(0), _source((void *)&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, hegyi@1123: /// but it is much more simple 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 hegyi@1124: /// and not on templatable built-in classes. When using the plain \ref Dijkstra hegyi@1124: /// the new class with the modified type comes from the original class by using the :: hegyi@1124: /// operator. In the case of \ref DijkstraWizard only 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; hegyi@1123: ///\brief The type of the map that stores the last but one hegyi@1123: ///nodes of the shortest paths. alpar@953: 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@1126: if(_source==0) throw UninitializedParameter(); alpar@1116: Dijkstra Dij(*(Graph*)_g,*(LengthMap*)_length); alpar@1116: if(_pred) Dij.predMap(*(PredMap*)_pred); alpar@1116: if(_predNode) Dij.predNodeMap(*(PredNodeMap*)_predNode); alpar@1116: if(_dist) Dij.distMap(*(DistMap*)_dist); alpar@1116: Dij.run(*(Node*)_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@1116: _source=(void *)&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: hegyi@1123: /// \ref named-templ-param "Named parameter" function for setting PredMap type hegyi@1123: hegyi@1123: /// \ref named-templ-param "Named parameter" function for setting PredMap type hegyi@1124: /// alpar@953: template alpar@1116: DijkstraWizard > predMap(const T &t) alpar@953: { alpar@1116: _pred=(void *)&t; alpar@1116: return DijkstraWizard >(*this); alpar@953: } alpar@953: alpar@1116: alpar@953: template alpar@1116: struct DefPredNodeMapBase : public Base { alpar@1116: typedef T PredNodeMap; alpar@1117: static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; }; alpar@1117: DefPredNodeMapBase(const Base &b) : Base(b) {} alpar@1116: }; alpar@1116: hegyi@1123: /// \ref named-templ-param "Named parameter" function for setting PredNodeMap type hegyi@1123: hegyi@1123: /// \ref named-templ-param "Named parameter" function for setting PredNodeMap type hegyi@1124: /// alpar@953: template alpar@1116: DijkstraWizard > predNodeMap(const T &t) alpar@953: { alpar@1116: _predNode=(void *)&t; alpar@1116: return DijkstraWizard >(*this); alpar@953: } 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: hegyi@1123: /// \ref named-templ-param "Named parameter" function for setting DistMap type hegyi@1123: hegyi@1123: /// \ref named-templ-param "Named parameter" function for setting DistMap type hegyi@1124: /// alpar@953: template alpar@1116: DijkstraWizard > distMap(const T &t) alpar@953: { alpar@1116: _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@1116: source=(void *)&s; alpar@953: return *this; alpar@953: } alpar@953: alpar@953: }; alpar@255: alpar@953: ///\e alpar@953: alpar@954: ///\todo Please document... alpar@953: /// 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@430: /// @} alpar@255: alpar@921: } //END OF NAMESPACE LEMON alpar@255: alpar@255: #endif alpar@255: