alpar@906: /* -*- C++ -*- ladanyi@1435: * lemon/dijkstra.h - Part of LEMON, a generic C++ optimization library alpar@906: * alpar@1164: * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@1359: * (Egervary Research Group on Combinatorial Optimization, 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@1283: /// alpar@1283: ///\todo getPath() should be implemented! (also for BFS and DFS) alpar@1734: ///\todo dijkstraZero() solution should be revised. 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@1734: template T dijkstraZero() {return 0;} 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; deba@1721: /// The cross reference type used by heap. deba@1721: deba@1721: /// The cross reference type used by heap. deba@1721: /// Usually it is \c Graph::NodeMap. deba@1721: typedef typename Graph::template NodeMap HeapCrossRef; deba@1721: ///Instantiates a HeapCrossRef. deba@1721: deba@1721: ///This function instantiates a \ref HeapCrossRef. deba@1721: /// \param G is the graph, to which we would like to define the deba@1721: /// HeapCrossRef. deba@1721: static HeapCrossRef *createHeapCrossRef(const GR &G) deba@1721: { deba@1721: return new HeapCrossRef(G); deba@1721: } deba@1721: 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 deba@1709: typedef BinHeap > Heap; alpar@953: deba@1721: static Heap *createHeap(HeapCrossRef& R) deba@1721: { deba@1721: return new Heap(R); deba@1721: } deba@1721: 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@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@1536: ///\param g is the graph, to which alpar@1218: ///we would like to define the \ref ProcessedMap alpar@1536: #ifdef DOXYGEN alpar@1536: static ProcessedMap *createProcessedMap(const GR &g) alpar@1536: #else alpar@1366: static ProcessedMap *createProcessedMap(const GR &) alpar@1536: #endif 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: ///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; deba@1721: ///The cross reference type used for the current heap. deba@1721: typedef typename TR::HeapCrossRef HeapCrossRef; 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 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; deba@1721: ///Pointer to the heap cross references. deba@1721: HeapCrossRef *_heap_cross_ref; deba@1721: ///Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not. deba@1721: bool local_heap_cross_ref; deba@1721: ///Pointer to the heap. deba@1721: Heap *_heap; deba@1721: ///Indicates if \ref _heap is locally allocated (\c true) or not. deba@1721: bool local_heap; alpar@688: 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(!_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: } deba@1721: if (!_heap_cross_ref) { deba@1721: local_heap_cross_ref = true; deba@1721: _heap_cross_ref = Traits::createHeapCrossRef(*G); deba@1721: } deba@1721: if (!_heap) { deba@1721: local_heap = true; deba@1721: _heap = Traits::createHeap(*_heap_cross_ref); deba@1721: } alpar@688: } alpar@255: alpar@255: public : deba@1710: deba@1710: typedef Dijkstra Create; 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 deba@1709: struct DefPredMap deba@1709: : public Dijkstra< Graph, LengthMap, DefPredMapTraits > { deba@1709: typedef Dijkstra< Graph, LengthMap, DefPredMapTraits > Create; deba@1709: }; 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 deba@1709: struct DefDistMap deba@1709: : public Dijkstra< Graph, LengthMap, DefDistMapTraits > { deba@1709: typedef Dijkstra< Graph, LengthMap, DefDistMapTraits > Create; deba@1709: }; 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 deba@1709: struct DefProcessedMap deba@1709: : public Dijkstra< Graph, LengthMap, DefProcessedMapTraits > { deba@1709: typedef Dijkstra< Graph, LengthMap, DefProcessedMapTraits > Create; deba@1709: }; 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 deba@1709: struct DefProcessedMapToBeDefaultMap deba@1709: : public Dijkstra< Graph, LengthMap, DefGraphProcessedMapTraits> { deba@1709: typedef Dijkstra< Graph, LengthMap, DefGraphProcessedMapTraits> Create; deba@1709: }; deba@1721: deba@1721: template deba@1721: struct DefHeapTraits : public Traits { deba@1721: typedef CR HeapCrossRef; deba@1721: typedef H Heap; deba@1741: static HeapCrossRef *createHeapCrossRef(const Graph &) { deba@1741: throw UninitializedParameter(); deba@1721: } deba@1741: static Heap *createHeap(HeapCrossRef &) deba@1721: { deba@1741: throw UninitializedParameter(); deba@1721: } deba@1721: }; deba@1721: ///\ref named-templ-param "Named parameter" for setting heap and cross deba@1721: ///reference type deba@1721: deba@1721: ///\ref named-templ-param "Named parameter" for setting heap and cross deba@1721: ///reference type deba@1721: /// deba@1721: template > deba@1721: struct DefHeap deba@1721: : public Dijkstra< Graph, LengthMap, DefHeapTraits > { deba@1721: typedef Dijkstra< Graph, LengthMap, DefHeapTraits > Create; deba@1721: }; deba@1741: deba@1741: template deba@1741: struct DefStandardHeapTraits : public Traits { deba@1741: typedef CR HeapCrossRef; deba@1741: typedef H Heap; deba@1741: static HeapCrossRef *createHeapCrossRef(const Graph &G) { deba@1741: return new HeapCrossRef(G); deba@1741: } deba@1741: static Heap *createHeap(HeapCrossRef &R) deba@1741: { deba@1741: return new Heap(R); deba@1741: } deba@1741: }; deba@1741: ///\ref named-templ-param "Named parameter" for setting heap and cross deba@1741: ///reference type with automatic allocation deba@1741: deba@1741: ///\ref named-templ-param "Named parameter" for setting heap and cross deba@1741: ///reference type. It can allocate the heap and the cross reference deba@1741: ///object if the cross reference's constructor waits for the graph as deba@1741: ///parameter and the heap's constructor waits for the cross reference. deba@1741: template > deba@1741: struct DefStandardHeap deba@1741: : public Dijkstra< Graph, LengthMap, DefStandardHeapTraits > { deba@1741: typedef Dijkstra< Graph, LengthMap, DefStandardHeapTraits > deba@1741: Create; deba@1741: }; alpar@1128: alpar@1128: ///@} alpar@1128: alpar@1128: deba@1710: protected: deba@1710: deba@1710: Dijkstra() {} deba@1710: 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: _dist(NULL), local_dist(false), alpar@1218: _processed(NULL), local_processed(false), deba@1721: _heap_cross_ref(NULL), local_heap_cross_ref(false), deba@1721: _heap(NULL), local_heap(false) alpar@688: { } alpar@688: alpar@802: ///Destructor. alpar@688: ~Dijkstra() alpar@688: { alpar@1119: if(local_pred) delete _pred; alpar@1130: if(local_dist) delete _dist; alpar@1218: if(local_processed) delete _processed; deba@1721: if(local_heap_cross_ref) delete _heap_cross_ref; deba@1721: if(local_heap) delete _heap; 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 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: deba@1741: ///Sets the heap and the cross reference used by algorithm. deba@1741: deba@1741: ///Sets the heap and the cross reference used by algorithm. deba@1741: ///If you don't use this function before calling \ref run(), deba@1741: ///it will allocate one. The destuctor deallocates this deba@1741: ///automatically allocated map, of course. deba@1741: ///\return (*this) deba@1741: Dijkstra &heap(Heap& heap, HeapCrossRef &crossRef) deba@1741: { deba@1741: if(local_heap_cross_ref) { deba@1741: delete _heap_cross_ref; deba@1741: local_heap_cross_ref=false; deba@1741: } deba@1741: _heap_cross_ref = &crossRef; deba@1741: if(local_heap) { deba@1741: delete _heap; deba@1741: local_heap=false; deba@1741: } deba@1741: _heap = &heap; deba@1741: return *this; deba@1741: } deba@1741: 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@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: void init() alpar@1128: { alpar@1128: create_maps(); deba@1721: _heap->clear(); alpar@774: for ( NodeIt u(*G) ; u!=INVALID ; ++u ) { alpar@1119: _pred->set(u,INVALID); alpar@1218: _processed->set(u,false); deba@1721: _heap_cross_ref->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@1734: void addSource(Node s,Value dst=dijkstraZero()) alpar@1128: { deba@1721: if(_heap->state(s) != Heap::IN_HEAP) { deba@1721: _heap->push(s,dst); deba@1721: } else if((*_heap)[s]push(s,dst); alpar@1155: _pred->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@1516: ///\return The processed node. alpar@1516: /// alpar@1155: ///\warning The priority heap must not be empty! alpar@1516: Node processNextNode() alpar@1128: { deba@1721: Node v=_heap->top(); deba@1721: Value oldvalue=_heap->prio(); deba@1721: _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); deba@1721: switch(_heap->state(w)) { alpar@1128: case Heap::PRE_HEAP: deba@1721: _heap->push(w,oldvalue+(*length)[e]); alpar@1128: _pred->set(w,e); alpar@1128: break; alpar@1128: case Heap::IN_HEAP: deba@1721: if ( oldvalue+(*length)[e] < (*_heap)[w] ) { deba@1721: _heap->decrease(w, oldvalue+(*length)[e]); alpar@1119: _pred->set(w,e); alpar@694: } alpar@1128: break; alpar@1128: case Heap::POST_HEAP: alpar@1128: break; alpar@694: } alpar@694: } alpar@1516: return v; alpar@694: } alpar@1128: alpar@1665: ///Next node to be processed. alpar@1665: alpar@1665: ///Next node to be processed. alpar@1665: /// alpar@1665: ///\return The next node to be processed or INVALID if the priority heap alpar@1665: /// is empty. deba@1694: Node nextNode() alpar@1665: { deba@1721: return _heap->empty()?_heap->top():INVALID; alpar@1665: } alpar@1665: 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 deba@1721: 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: /// deba@1721: 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: { deba@1721: 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: { deba@1721: while ( !_heap->empty() && _heap->top()!=dest ) processNextNode(); deba@1721: if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio()); 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. deba@1345: template deba@1345: void start(const NodeBoolMap &nm) alpar@1130: { deba@1721: while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode(); deba@1721: if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio()); 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@1734: return (*_pred)[t]==INVALID?dijkstraZero():(*_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: alpar@1283: ///Copies the shortest path to \c t into \c p alpar@1283: alpar@1283: ///This function copies the shortest path to \c t into \c p. alpar@1536: ///If it \c t is a source itself or unreachable, then it does not alpar@1283: ///alter \c p. alpar@1283: ///\todo Is it the right way to handle unreachable nodes? alpar@1283: ///\return Returns \c true if a path to \c t was actually copied to \c p, alpar@1283: ///\c false otherwise. alpar@1283: ///\sa DirPath alpar@1283: template alpar@1283: bool getPath(P &p,Node t) alpar@1283: { alpar@1283: if(reached(t)) { alpar@1283: p.clear(); alpar@1283: typename P::Builder b(p); alpar@1283: for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t)) alpar@1283: b.pushFront(pred(t)); alpar@1283: b.commit(); alpar@1283: return true; alpar@1283: } alpar@1283: return false; alpar@1283: } alpar@1283: 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 alpar@1631: ///\ref predNode(). \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 alpar@1631: ///tree used in \ref pred(). \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: ///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: /// deba@1721: bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; } alpar@1734: alpar@1734: ///Checks if a node is processed. alpar@1734: alpar@1734: ///Returns \c true if \c v is processed, i.e. the shortest alpar@1734: ///path to \c v has already found. alpar@1734: ///\pre \ref run() must be called before using this function. alpar@1734: /// alpar@1734: bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_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: deba@1721: /// The cross reference type used by heap. deba@1721: deba@1721: /// The cross reference type used by heap. deba@1721: /// Usually it is \c Graph::NodeMap. deba@1721: typedef typename Graph::template NodeMap HeapCrossRef; deba@1721: ///Instantiates a HeapCrossRef. deba@1721: deba@1721: ///This function instantiates a \ref HeapCrossRef. deba@1721: /// \param G is the graph, to which we would like to define the deba@1721: /// HeapCrossRef. deba@1721: /// \todo The graph alone may be insufficient for the initialization deba@1721: static HeapCrossRef *createHeapCrossRef(const GR &G) deba@1721: { deba@1721: return new HeapCrossRef(G); deba@1721: } deba@1721: deba@1721: ///The heap type used by Dijkstra algorithm. deba@1721: alpar@1218: ///The heap type used by Dijkstra algorithm. alpar@1218: /// alpar@1218: ///\sa BinHeap alpar@1218: ///\sa Dijkstra deba@1721: typedef BinHeap, alpar@1218: std::less > Heap; alpar@1218: deba@1721: static Heap *createHeap(HeapCrossRef& R) deba@1721: { deba@1721: return new Heap(R); deba@1721: } deba@1721: 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@1536: ///\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@1536: #ifdef DOXYGEN alpar@1536: static PredMap *createPredMap(const GR &g) alpar@1536: #else alpar@1367: static PredMap *createPredMap(const GR &) alpar@1536: #endif 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@1536: ///\param g is the graph, to which alpar@1218: ///we would like to define the \ref ProcessedMap alpar@1536: #ifdef DOXYGEN alpar@1536: static ProcessedMap *createProcessedMap(const GR &g) alpar@1536: #else alpar@1367: static ProcessedMap *createProcessedMap(const GR &) alpar@1536: #endif 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@1536: ///\param g is the graph, to which we would like to define the \ref DistMap alpar@1536: #ifdef DOXYGEN alpar@1536: static DistMap *createDistMap(const GR &g) alpar@1536: #else alpar@1367: static DistMap *createDistMap(const GR &) alpar@1536: #endif 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@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: _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: _dist(0), _source(s) {} alpar@1116: alpar@1116: }; alpar@1116: alpar@1229: /// A class to make the usage of Dijkstra algorithm easier 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 deba@1721: /// it initiates a plain \ref Dijkstra class, and calls the \ref deba@1721: /// Dijkstra::run 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: ///The type of the map that stores the dists of the nodes. alpar@953: typedef typename TR::DistMap DistMap; 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@1345: dij(*(Graph*)Base::_g,*(LengthMap*)Base::_length); deba@1345: if(Base::_pred) dij.predMap(*(PredMap*)Base::_pred); deba@1345: if(Base::_dist) dij.distMap(*(DistMap*)Base::_dist); deba@1345: 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@1367: static PredMap *createPredMap(const Graph &) { return 0; }; alpar@1236: DefPredMapBase(const TR &b) : TR(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: template alpar@1116: struct DefDistMapBase : public Base { alpar@1116: typedef T DistMap; alpar@1367: static DistMap *createDistMap(const Graph &) { return 0; }; alpar@1236: DefDistMapBase(const TR &b) : TR(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