- PredNodeMap is a NullMap by default
authoralpar
Sun, 06 Feb 2005 20:00:56 +0000
changeset 113047ef467ccf70
parent 1129 4e26fd7ffcdc
child 1131 425731cb66de
- PredNodeMap is a NullMap by default
- Execution with stop condition
- Find shortest path between two nodes
src/work/alpar/dijkstra.h
     1.1 --- a/src/work/alpar/dijkstra.h	Sun Feb 06 15:49:37 2005 +0000
     1.2 +++ b/src/work/alpar/dijkstra.h	Sun Feb 06 20:00:56 2005 +0000
     1.3 @@ -85,14 +85,14 @@
     1.4      ///nodes of the shortest paths.
     1.5      ///It must meet the \ref concept::WriteMap "WriteMap" concept.
     1.6      ///
     1.7 -    typedef typename Graph::template NodeMap<typename GR::Node> PredNodeMap;
     1.8 +    typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
     1.9      ///Instantiates a PredNodeMap.
    1.10      
    1.11      ///This function instantiates a \ref PredNodeMap. 
    1.12      ///\param G is the graph, to which we would like to define the \ref PredNodeMap
    1.13      static PredNodeMap *createPredNodeMap(const GR &G)
    1.14      {
    1.15 -      return new PredNodeMap(G);
    1.16 +      return new PredNodeMap();
    1.17      }
    1.18  
    1.19      ///The type of the map that stores whether a nodes is reached.
    1.20 @@ -222,13 +222,13 @@
    1.21      ///Indicates if \ref _pred is locally allocated (\c true) or not.
    1.22      bool local_pred;
    1.23      ///Pointer to the map of predecessors nodes.
    1.24 -    PredNodeMap *pred_node;
    1.25 -    ///Indicates if \ref pred_node is locally allocated (\c true) or not.
    1.26 -    bool local_pred_node;
    1.27 +    PredNodeMap *_predNode;
    1.28 +    ///Indicates if \ref _predNode is locally allocated (\c true) or not.
    1.29 +    bool local_predNode;
    1.30      ///Pointer to the map of distances.
    1.31 -    DistMap *distance;
    1.32 -    ///Indicates if \ref distance is locally allocated (\c true) or not.
    1.33 -    bool local_distance;
    1.34 +    DistMap *_dist;
    1.35 +    ///Indicates if \ref _dist is locally allocated (\c true) or not.
    1.36 +    bool local_dist;
    1.37      ///Pointer to the map of reached status of the nodes.
    1.38      ReachedMap *_reached;
    1.39      ///Indicates if \ref _reached is locally allocated (\c true) or not.
    1.40 @@ -247,13 +247,13 @@
    1.41  	local_pred = true;
    1.42  	_pred = Traits::createPredMap(*G);
    1.43        }
    1.44 -      if(!pred_node) {
    1.45 -	local_pred_node = true;
    1.46 -	pred_node = Traits::createPredNodeMap(*G);
    1.47 +      if(!_predNode) {
    1.48 +	local_predNode = true;
    1.49 +	_predNode = Traits::createPredNodeMap(*G);
    1.50        }
    1.51 -      if(!distance) {
    1.52 -	local_distance = true;
    1.53 -	distance = Traits::createDistMap(*G);
    1.54 +      if(!_dist) {
    1.55 +	local_dist = true;
    1.56 +	_dist = Traits::createDistMap(*G);
    1.57        }
    1.58        if(!_reached) {
    1.59  	local_reached = true;
    1.60 @@ -369,8 +369,8 @@
    1.61      Dijkstra(const Graph& _G, const LengthMap& _length) :
    1.62        G(&_G), length(&_length),
    1.63        _pred(NULL), local_pred(false),
    1.64 -      pred_node(NULL), local_pred_node(false),
    1.65 -      distance(NULL), local_distance(false),
    1.66 +      _predNode(NULL), local_predNode(false),
    1.67 +      _dist(NULL), local_dist(false),
    1.68        _reached(NULL), local_reached(false),
    1.69        _heap_map(*G,-1),_heap(_heap_map)
    1.70      { }
    1.71 @@ -379,8 +379,8 @@
    1.72      ~Dijkstra() 
    1.73      {
    1.74        if(local_pred) delete _pred;
    1.75 -      if(local_pred_node) delete pred_node;
    1.76 -      if(local_distance) delete distance;
    1.77 +      if(local_predNode) delete _predNode;
    1.78 +      if(local_dist) delete _dist;
    1.79        if(local_reached) delete _reached;
    1.80      }
    1.81  
    1.82 @@ -420,11 +420,11 @@
    1.83      ///\return <tt> (*this) </tt>
    1.84      Dijkstra &predNodeMap(PredNodeMap &m) 
    1.85      {
    1.86 -      if(local_pred_node) {
    1.87 -	delete pred_node;
    1.88 -	local_pred_node=false;
    1.89 +      if(local_predNode) {
    1.90 +	delete _predNode;
    1.91 +	local_predNode=false;
    1.92        }
    1.93 -      pred_node = &m;
    1.94 +      _predNode = &m;
    1.95        return *this;
    1.96      }
    1.97  
    1.98 @@ -437,14 +437,23 @@
    1.99      ///\return <tt> (*this) </tt>
   1.100      Dijkstra &distMap(DistMap &m) 
   1.101      {
   1.102 -      if(local_distance) {
   1.103 -	delete distance;
   1.104 -	local_distance=false;
   1.105 +      if(local_dist) {
   1.106 +	delete _dist;
   1.107 +	local_dist=false;
   1.108        }
   1.109 -      distance = &m;
   1.110 +      _dist = &m;
   1.111        return *this;
   1.112      }
   1.113  
   1.114 +  private:
   1.115 +    void finalizeNodeData(Node v,Value dst)
   1.116 +    {
   1.117 +      _reached->set(v,true);
   1.118 +      _dist->set(v, dst);
   1.119 +      _predNode->set(v,G->source((*_pred)[v]));
   1.120 +    }
   1.121 +
   1.122 +  public:
   1.123      ///\name Excetution control
   1.124      ///The simplest way to execute the algorithm is to use
   1.125      ///\ref run().
   1.126 @@ -467,7 +476,7 @@
   1.127        
   1.128        for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
   1.129  	_pred->set(u,INVALID);
   1.130 -	pred_node->set(u,INVALID);
   1.131 +	_predNode->set(u,INVALID);
   1.132  	///\todo *_reached is not set to false.
   1.133  	_heap_map.set(u,Heap::PRE_HEAP);
   1.134        }
   1.135 @@ -490,10 +499,9 @@
   1.136      void processNode()
   1.137      {
   1.138        Node v=_heap.top(); 
   1.139 -      _reached->set(v,true);
   1.140        Value oldvalue=_heap[v];
   1.141        _heap.pop();
   1.142 -      distance->set(v, oldvalue);
   1.143 +      finalizeNodeData(v,oldvalue);
   1.144        
   1.145        for(OutEdgeIt e(*G,v); e!=INVALID; ++e) {
   1.146  	Node w=G->target(e); 
   1.147 @@ -501,13 +509,13 @@
   1.148  	case Heap::PRE_HEAP:
   1.149  	  _heap.push(w,oldvalue+(*length)[e]); 
   1.150  	  _pred->set(w,e);
   1.151 -	  pred_node->set(w,v);
   1.152 +//  	  _predNode->set(w,v);
   1.153  	  break;
   1.154  	case Heap::IN_HEAP:
   1.155  	  if ( oldvalue+(*length)[e] < _heap[w] ) {
   1.156  	    _heap.decrease(w, oldvalue+(*length)[e]); 
   1.157  	    _pred->set(w,e);
   1.158 -	    pred_node->set(w,v);
   1.159 +// 	    _predNode->set(w,v);
   1.160  	  }
   1.161  	  break;
   1.162  	case Heap::POST_HEAP:
   1.163 @@ -516,12 +524,12 @@
   1.164        }
   1.165      }
   1.166  
   1.167 -    ///Starts the execution of the algorithm.
   1.168 +    ///Executes the algorithm.
   1.169  
   1.170 -    ///Starts the execution of the algorithm.
   1.171 +    ///Executes the algorithm.
   1.172      ///
   1.173 -    ///\pre init() must be called before and at least one node should be added
   1.174 -    ///with addSource().
   1.175 +    ///\pre init() must be called and at least one node should be added
   1.176 +    ///with addSource() before using this function.
   1.177      ///
   1.178      ///This method runs the %Dijkstra algorithm from the root node(s)
   1.179      ///in order to
   1.180 @@ -535,12 +543,12 @@
   1.181        while ( !_heap.empty() ) processNode();
   1.182      }
   1.183      
   1.184 -    ///Starts the execution of the algorithm until \c dest is reached.
   1.185 +    ///Executes the algorithm until \c dest is reached.
   1.186  
   1.187 -    ///Starts the execution of the algorithm until \c dest is reached.
   1.188 +    ///Executes the algorithm until \c dest is reached.
   1.189      ///
   1.190 -    ///\pre init() must be called before and at least one node should be added
   1.191 -    ///with addSource().
   1.192 +    ///\pre init() must be called and at least one node should be added
   1.193 +    ///with addSource() before using this function.
   1.194      ///
   1.195      ///This method runs the %Dijkstra algorithm from the root node(s)
   1.196      ///in order to
   1.197 @@ -551,7 +559,24 @@
   1.198      ///
   1.199      void start(Node dest)
   1.200      {
   1.201 -      while ( !_heap.empty() && _heap.top()!=dest) processNode();
   1.202 +      while ( !_heap.empty() && _heap.top()!=dest ) processNode();
   1.203 +      if ( _heap.top()==dest ) finalizeNodeData(_heap.top());
   1.204 +    }
   1.205 +    
   1.206 +    ///Executes the algorithm until a condition is met.
   1.207 +
   1.208 +    ///Executes the algorithm until a condition is met.
   1.209 +    ///
   1.210 +    ///\pre init() must be called and at least one node should be added
   1.211 +    ///with addSource() before using this function.
   1.212 +    ///
   1.213 +    ///\param nm must be a bool (or convertible) node map. The algorithm
   1.214 +    ///will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
   1.215 +    template<class NM>
   1.216 +    void start(const NM &nm)
   1.217 +    {
   1.218 +      while ( !_heap.empty() && !mn[_heap.top()] ) processNode();
   1.219 +      if ( !_heap.empty() ) finalizeNodeData(_heap.top());
   1.220      }
   1.221      
   1.222      ///Runs %Dijkstra algorithm from node \c s.
   1.223 @@ -575,6 +600,26 @@
   1.224        start();
   1.225      }
   1.226      
   1.227 +    ///Finds the shortest path between \c s and \c t.
   1.228 +    
   1.229 +    ///Finds the shortest path between \c s and \c t.
   1.230 +    ///
   1.231 +    ///\return The length of the shortest s---t path if there exists one,
   1.232 +    ///0 otherwise.
   1.233 +    ///\note Apart from the return value, d.run(s) is
   1.234 +    ///just a shortcut of the following code.
   1.235 +    ///\code
   1.236 +    ///  d.init();
   1.237 +    ///  d.addSource(s);
   1.238 +    ///  d.start(t);
   1.239 +    ///\endcode
   1.240 +    Value run(Node s,Node t) {
   1.241 +      init();
   1.242 +      addSource(s);
   1.243 +      start(t);
   1.244 +      return (*_pred)[t]==INVALID?0:(*_dist)[t];
   1.245 +    }
   1.246 +    
   1.247      ///@}
   1.248  
   1.249      ///\name Query Functions
   1.250 @@ -591,7 +636,7 @@
   1.251      ///\pre \ref run() must be called before using this function.
   1.252      ///\warning If node \c v in unreachable from the root the return value
   1.253      ///of this funcion is undefined.
   1.254 -    Value dist(Node v) const { return (*distance)[v]; }
   1.255 +    Value dist(Node v) const { return (*_dist)[v]; }
   1.256  
   1.257      ///Returns the 'previous edge' of the shortest path tree.
   1.258  
   1.259 @@ -613,13 +658,14 @@
   1.260      ///\c v=s. The shortest path tree used here is equal to the shortest path
   1.261      ///tree used in \ref pred(Node v).  \pre \ref run() must be called before
   1.262      ///using this function.
   1.263 -    Node predNode(Node v) const { return (*pred_node)[v]; }
   1.264 +    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
   1.265 +				  G->source((*_pred)[v]); }
   1.266      
   1.267      ///Returns a reference to the NodeMap of distances.
   1.268  
   1.269      ///Returns a reference to the NodeMap of distances. \pre \ref run() must
   1.270      ///be called before using this function.
   1.271 -    const DistMap &distMap() const { return *distance;}
   1.272 +    const DistMap &distMap() const { return *_dist;}
   1.273   
   1.274      ///Returns a reference to the shortest path tree map.
   1.275  
   1.276 @@ -633,7 +679,7 @@
   1.277      ///Returns a reference to the NodeMap of the last but one nodes of the
   1.278      ///shortest path tree.
   1.279      ///\pre \ref run() must be called before using this function.
   1.280 -    const PredNodeMap &predNodeMap() const { return *pred_node;}
   1.281 +    const PredNodeMap &predNodeMap() const { return *_predNode;}
   1.282  
   1.283      ///Checks if a node is reachable from the root.
   1.284