dijkstra.h

Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 * src/lemon/dijkstra.h - Part of LEMON, a generic C++ optimization library 00003 * 00004 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 00005 * (Egervary Combinatorial Optimization Research Group, EGRES). 00006 * 00007 * Permission to use, modify and distribute this software is granted 00008 * provided that this copyright notice appears in all copies. For 00009 * precise terms see the accompanying LICENSE file. 00010 * 00011 * This software is provided "AS IS" with no warranty of any kind, 00012 * express or implied, and with no claim as to its suitability for any 00013 * purpose. 00014 * 00015 */ 00016 00017 #ifndef LEMON_DIJKSTRA_H 00018 #define LEMON_DIJKSTRA_H 00019 00023 00024 #include <lemon/bin_heap.h> 00025 #include <lemon/invalid.h> 00026 00027 namespace lemon { 00028 00031 00033 00060 00061 #ifdef DOXYGEN 00062 template <typename GR, 00063 typename LM, 00064 typename Heap> 00065 #else 00066 template <typename GR, 00067 typename LM=typename GR::template EdgeMap<int>, 00068 template <class,class,class,class> class Heap = BinHeap > 00069 #endif 00070 class Dijkstra{ 00071 public: 00073 typedef GR Graph; 00075 typedef typename Graph::Node Node; 00077 typedef typename Graph::NodeIt NodeIt; 00079 typedef typename Graph::Edge Edge; 00081 typedef typename Graph::OutEdgeIt OutEdgeIt; 00082 00084 typedef typename LM::ValueType ValueType; 00086 typedef LM LengthMap; 00089 typedef typename Graph::template NodeMap<Edge> PredMap; 00092 typedef typename Graph::template NodeMap<Node> PredNodeMap; 00094 typedef typename Graph::template NodeMap<ValueType> DistMap; 00095 00096 private: 00098 const Graph *G; 00100 const LM *length; 00102 PredMap *predecessor; 00104 bool local_predecessor; 00106 PredNodeMap *pred_node; 00108 bool local_pred_node; 00110 DistMap *distance; 00112 bool local_distance; 00113 00115 Node source; 00116 00118 00121 void init_maps() 00122 { 00123 if(!predecessor) { 00124 local_predecessor = true; 00125 predecessor = new PredMap(*G); 00126 } 00127 if(!pred_node) { 00128 local_pred_node = true; 00129 pred_node = new PredNodeMap(*G); 00130 } 00131 if(!distance) { 00132 local_distance = true; 00133 distance = new DistMap(*G); 00134 } 00135 } 00136 00137 public : 00139 00142 Dijkstra(const Graph& _G, const LM& _length) : 00143 G(&_G), length(&_length), 00144 predecessor(NULL), local_predecessor(false), 00145 pred_node(NULL), local_pred_node(false), 00146 distance(NULL), local_distance(false) 00147 { } 00148 00150 ~Dijkstra() 00151 { 00152 if(local_predecessor) delete predecessor; 00153 if(local_pred_node) delete pred_node; 00154 if(local_distance) delete distance; 00155 } 00156 00158 00161 Dijkstra &setLengthMap(const LM &m) 00162 { 00163 length = &m; 00164 return *this; 00165 } 00166 00168 00174 Dijkstra &setPredMap(PredMap &m) 00175 { 00176 if(local_predecessor) { 00177 delete predecessor; 00178 local_predecessor=false; 00179 } 00180 predecessor = &m; 00181 return *this; 00182 } 00183 00185 00191 Dijkstra &setPredNodeMap(PredNodeMap &m) 00192 { 00193 if(local_pred_node) { 00194 delete pred_node; 00195 local_pred_node=false; 00196 } 00197 pred_node = &m; 00198 return *this; 00199 } 00200 00202 00208 Dijkstra &setDistMap(DistMap &m) 00209 { 00210 if(local_distance) { 00211 delete distance; 00212 local_distance=false; 00213 } 00214 distance = &m; 00215 return *this; 00216 } 00217 00219 00226 00227 void run(Node s) { 00228 00229 init_maps(); 00230 00231 source = s; 00232 00233 for ( NodeIt u(*G) ; u!=INVALID ; ++u ) { 00234 predecessor->set(u,INVALID); 00235 pred_node->set(u,INVALID); 00236 } 00237 00238 typename GR::template NodeMap<int> heap_map(*G,-1); 00239 00240 typedef Heap<Node, ValueType, typename GR::template NodeMap<int>, 00241 std::less<ValueType> > 00242 HeapType; 00243 00244 HeapType heap(heap_map); 00245 00246 heap.push(s,0); 00247 00248 while ( !heap.empty() ) { 00249 00250 Node v=heap.top(); 00251 ValueType oldvalue=heap[v]; 00252 heap.pop(); 00253 distance->set(v, oldvalue); 00254 00255 00256 for(OutEdgeIt e(*G,v); e!=INVALID; ++e) { 00257 Node w=G->head(e); 00258 switch(heap.state(w)) { 00259 case HeapType::PRE_HEAP: 00260 heap.push(w,oldvalue+(*length)[e]); 00261 predecessor->set(w,e); 00262 pred_node->set(w,v); 00263 break; 00264 case HeapType::IN_HEAP: 00265 if ( oldvalue+(*length)[e] < heap[w] ) { 00266 heap.decrease(w, oldvalue+(*length)[e]); 00267 predecessor->set(w,e); 00268 pred_node->set(w,v); 00269 } 00270 break; 00271 case HeapType::POST_HEAP: 00272 break; 00273 } 00274 } 00275 } 00276 } 00277 00279 00284 ValueType dist(Node v) const { return (*distance)[v]; } 00285 00287 00296 Edge pred(Node v) const { return (*predecessor)[v]; } 00297 00299 00306 Node predNode(Node v) const { return (*pred_node)[v]; } 00307 00309 00312 const DistMap &distMap() const { return *distance;} 00313 00315 00319 const PredMap &predMap() const { return *predecessor;} 00320 00322 00326 const PredNodeMap &predNodeMap() const { return *pred_node;} 00327 00329 00334 bool reached(Node v) { return v==source || (*predecessor)[v]!=INVALID; } 00335 00336 }; 00337 00339 00340 } //END OF NAMESPACE LEMON 00341 00342 #endif 00343 00344

Generated on Thu Sep 30 12:18:33 2004 for LEMON by doxygen 1.3.8