00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef LEMON_DFS_H
00018 #define LEMON_DFS_H
00019
00023
00024 #include <lemon/list_graph.h>
00025 #include <lemon/graph_utils.h>
00026 #include <lemon/invalid.h>
00027 #include <lemon/error.h>
00028 #include <lemon/maps.h>
00029
00030 namespace lemon {
00031
00032
00033
00035
00038 template<class GR>
00039 struct DfsDefaultTraits
00040 {
00042 typedef GR Graph;
00050 typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
00052
00056 static PredMap *createPredMap(const GR &G)
00057 {
00058 return new PredMap(G);
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00079
00083 typedef NullMap<typename Graph::Node,bool> ProcessedMap;
00085
00089 #ifdef DOXYGEN
00090 static ProcessedMap *createProcessedMap(const GR &g)
00091 #else
00092 static ProcessedMap *createProcessedMap(const GR &)
00093 #endif
00094 {
00095 return new ProcessedMap();
00096 }
00098
00102 typedef typename Graph::template NodeMap<bool> ReachedMap;
00104
00108 static ReachedMap *createReachedMap(const GR &G)
00109 {
00110 return new ReachedMap(G);
00111 }
00113
00117 typedef typename Graph::template NodeMap<int> DistMap;
00119
00122 static DistMap *createDistMap(const GR &G)
00123 {
00124 return new DistMap(G);
00125 }
00126 };
00127
00129
00144
00145 #ifdef DOXYGEN
00146 template <typename GR,
00147 typename TR>
00148 #else
00149 template <typename GR=ListGraph,
00150 typename TR=DfsDefaultTraits<GR> >
00151 #endif
00152 class Dfs {
00153 public:
00160 class UninitializedParameter : public lemon::UninitializedParameter {
00161 public:
00162 virtual const char* exceptionName() const {
00163 return "lemon::Dfs::UninitializedParameter";
00164 }
00165 };
00166
00167 typedef TR Traits;
00169 typedef typename TR::Graph Graph;
00171 typedef typename Graph::Node Node;
00173 typedef typename Graph::NodeIt NodeIt;
00175 typedef typename Graph::Edge Edge;
00177 typedef typename Graph::OutEdgeIt OutEdgeIt;
00178
00181 typedef typename TR::PredMap PredMap;
00182
00183
00184
00186 typedef typename TR::ReachedMap ReachedMap;
00188 typedef typename TR::ProcessedMap ProcessedMap;
00190 typedef typename TR::DistMap DistMap;
00191 private:
00193 const Graph *G;
00195 PredMap *_pred;
00197 bool local_pred;
00198
00199
00200
00201
00203 DistMap *_dist;
00205 bool local_dist;
00207 ReachedMap *_reached;
00209 bool local_reached;
00211 ProcessedMap *_processed;
00213 bool local_processed;
00214
00215 std::vector<typename Graph::OutEdgeIt> _stack;
00216 int _stack_head;
00217
00218
00219
00221
00224 void create_maps()
00225 {
00226 if(!_pred) {
00227 local_pred = true;
00228 _pred = Traits::createPredMap(*G);
00229 }
00230
00231
00232
00233
00234 if(!_dist) {
00235 local_dist = true;
00236 _dist = Traits::createDistMap(*G);
00237 }
00238 if(!_reached) {
00239 local_reached = true;
00240 _reached = Traits::createReachedMap(*G);
00241 }
00242 if(!_processed) {
00243 local_processed = true;
00244 _processed = Traits::createProcessedMap(*G);
00245 }
00246 }
00247
00248 public :
00249
00251
00253
00254 template <class T>
00255 struct DefPredMapTraits : public Traits {
00256 typedef T PredMap;
00257 static PredMap *createPredMap(const Graph &G)
00258 {
00259 throw UninitializedParameter();
00260 }
00261 };
00263
00266 template <class T>
00267 class DefPredMap : public Dfs< Graph,
00268 DefPredMapTraits<T> > { };
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 template <class T>
00288 struct DefDistMapTraits : public Traits {
00289 typedef T DistMap;
00290 static DistMap *createDistMap(const Graph &G)
00291 {
00292 throw UninitializedParameter();
00293 }
00294 };
00296
00299 template <class T>
00300 class DefDistMap : public Dfs< Graph,
00301 DefDistMapTraits<T> > { };
00302
00303 template <class T>
00304 struct DefReachedMapTraits : public Traits {
00305 typedef T ReachedMap;
00306 static ReachedMap *createReachedMap(const Graph &G)
00307 {
00308 throw UninitializedParameter();
00309 }
00310 };
00312
00315 template <class T>
00316 class DefReachedMap : public Dfs< Graph,
00317 DefReachedMapTraits<T> > { };
00318
00319 struct DefGraphReachedMapTraits : public Traits {
00320 typedef typename Graph::template NodeMap<bool> ReachedMap;
00321 static ReachedMap *createReachedMap(const Graph &G)
00322 {
00323 return new ReachedMap(G);
00324 }
00325 };
00326 template <class T>
00327 struct DefProcessedMapTraits : public Traits {
00328 typedef T ProcessedMap;
00329 static ProcessedMap *createProcessedMap(const Graph &G)
00330 {
00331 throw UninitializedParameter();
00332 }
00333 };
00335
00338 template <class T>
00339 class DefProcessedMap : public Dfs< Graph,
00340 DefProcessedMapTraits<T> > { };
00341
00342 struct DefGraphProcessedMapTraits : public Traits {
00343 typedef typename Graph::template NodeMap<bool> ProcessedMap;
00344 static ProcessedMap *createProcessedMap(const Graph &G)
00345 {
00346 return new ProcessedMap(G);
00347 }
00348 };
00355 template <class T>
00356 class DefProcessedMapToBeDefaultMap :
00357 public Dfs< Graph,
00358 DefGraphProcessedMapTraits> { };
00359
00361
00362 public:
00363
00365
00368 Dfs(const Graph& _G) :
00369 G(&_G),
00370 _pred(NULL), local_pred(false),
00371
00372 _dist(NULL), local_dist(false),
00373 _reached(NULL), local_reached(false),
00374 _processed(NULL), local_processed(false)
00375 { }
00376
00378 ~Dfs()
00379 {
00380 if(local_pred) delete _pred;
00381
00382 if(local_dist) delete _dist;
00383 if(local_reached) delete _reached;
00384 if(local_processed) delete _processed;
00385 }
00386
00388
00394 Dfs &predMap(PredMap &m)
00395 {
00396 if(local_pred) {
00397 delete _pred;
00398 local_pred=false;
00399 }
00400 _pred = &m;
00401 return *this;
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00422
00428 Dfs &distMap(DistMap &m)
00429 {
00430 if(local_dist) {
00431 delete _dist;
00432 local_dist=false;
00433 }
00434 _dist = &m;
00435 return *this;
00436 }
00437
00439
00445 Dfs &reachedMap(ReachedMap &m)
00446 {
00447 if(local_reached) {
00448 delete _reached;
00449 local_reached=false;
00450 }
00451 _reached = &m;
00452 return *this;
00453 }
00454
00456
00462 Dfs &processedMap(ProcessedMap &m)
00463 {
00464 if(local_processed) {
00465 delete _processed;
00466 local_processed=false;
00467 }
00468 _processed = &m;
00469 return *this;
00470 }
00471
00472 public:
00482
00484
00486
00489 void init()
00490 {
00491 create_maps();
00492 _stack.resize(countNodes(*G));
00493 _stack_head=-1;
00494 for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
00495 _pred->set(u,INVALID);
00496
00497 _reached->set(u,false);
00498 _processed->set(u,false);
00499 }
00500 }
00501
00503
00507 void addSource(Node s)
00508 {
00509 if(!(*_reached)[s])
00510 {
00511 _reached->set(s,true);
00512 _pred->set(s,INVALID);
00513
00514 _stack[++_stack_head]=OutEdgeIt(*G,s);
00515 _dist->set(s,_stack_head);
00516 }
00517 }
00518
00520
00526 Edge processNextEdge()
00527 {
00528 Node m;
00529 Edge e=_stack[_stack_head];
00530 if(!(*_reached)[m=G->target(e)]) {
00531 _pred->set(m,e);
00532 _reached->set(m,true);
00533
00534 ++_stack_head;
00535 _stack[_stack_head] = OutEdgeIt(*G, m);
00536 _dist->set(m,_stack_head);
00537 }
00538 else {
00539 Node n;
00540 while(_stack_head>=0 &&
00541 (n=G->source(_stack[_stack_head]),
00542 ++_stack[_stack_head]==INVALID))
00543 {
00544 _processed->set(n,true);
00545 --_stack_head;
00546 }
00547 }
00548 return e;
00549 }
00550
00556 bool emptyQueue() { return _stack_head<0; }
00558
00561 int queueSize() { return _stack_head+1; }
00562
00564
00577 void start()
00578 {
00579 while ( !emptyQueue() ) processNextEdge();
00580 }
00581
00583
00596 void start(Node dest)
00597 {
00598 while ( !emptyQueue() && G->target(_stack[_stack_head])!=dest )
00599 processNextEdge();
00600 }
00601
00603
00614 template<class NM>
00615 void start(const NM &nm)
00616 {
00617 while ( !emptyQueue() && !nm[_stack[_stack_head]] ) processNextEdge();
00618 }
00619
00621
00635 void run(Node s) {
00636 init();
00637 addSource(s);
00638 start();
00639 }
00640
00642
00654 int run(Node s,Node t) {
00655 init();
00656 addSource(s);
00657 start(t);
00658 return reached(t)?_stack_head+1:0;
00659 }
00660
00662
00668
00670
00672
00681 template<class P>
00682 bool getPath(P &p,Node t)
00683 {
00684 if(reached(t)) {
00685 p.clear();
00686 typename P::Builder b(p);
00687 for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t))
00688 b.pushFront(pred(t));
00689 b.commit();
00690 return true;
00691 }
00692 return false;
00693 }
00694
00696
00701 int dist(Node v) const { return (*_dist)[v]; }
00702
00704
00715 Edge pred(Node v) const { return (*_pred)[v];}
00716
00718
00729 Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
00730 G->source((*_pred)[v]); }
00731
00733
00737 const DistMap &distMap() const { return *_dist;}
00738
00740
00745 const PredMap &predMap() const { return *_pred;}
00746
00747
00748
00749
00750
00751
00752
00753
00755
00761 bool reached(Node v) { return (*_reached)[v]; }
00762
00764 };
00765
00767
00770 template<class GR>
00771 struct DfsWizardDefaultTraits
00772 {
00774 typedef GR Graph;
00782 typedef NullMap<typename Graph::Node,typename GR::Edge> PredMap;
00784
00788 #ifdef DOXYGEN
00789 static PredMap *createPredMap(const GR &g)
00790 #else
00791 static PredMap *createPredMap(const GR &)
00792 #endif
00793 {
00794 return new PredMap();
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00815
00819 typedef NullMap<typename Graph::Node,bool> ProcessedMap;
00821
00825 #ifdef DOXYGEN
00826 static ProcessedMap *createProcessedMap(const GR &g)
00827 #else
00828 static ProcessedMap *createProcessedMap(const GR &)
00829 #endif
00830 {
00831 return new ProcessedMap();
00832 }
00834
00838 typedef typename Graph::template NodeMap<bool> ReachedMap;
00840
00844 static ReachedMap *createReachedMap(const GR &G)
00845 {
00846 return new ReachedMap(G);
00847 }
00849
00853 typedef NullMap<typename Graph::Node,int> DistMap;
00855
00858 #ifdef DOXYGEN
00859 static DistMap *createDistMap(const GR &g)
00860 #else
00861 static DistMap *createDistMap(const GR &)
00862 #endif
00863 {
00864 return new DistMap();
00865 }
00866 };
00867
00869
00876 template<class GR>
00877 class DfsWizardBase : public DfsWizardDefaultTraits<GR>
00878 {
00879
00880 typedef DfsWizardDefaultTraits<GR> Base;
00881 protected:
00883 typedef typename Base::Graph::Node Node;
00884
00886 void *_g;
00888 void *_reached;
00890 void *_processed;
00892 void *_pred;
00893
00894
00896 void *_dist;
00898 Node _source;
00899
00900 public:
00902
00905 DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
00906
00907 _dist(0), _source(INVALID) {}
00908
00910
00916 DfsWizardBase(const GR &g, Node s=INVALID) :
00917 _g((void *)&g), _reached(0), _processed(0), _pred(0),
00918
00919 _dist(0), _source(s) {}
00920
00921 };
00922
00924
00942 template<class TR>
00943 class DfsWizard : public TR
00944 {
00945 typedef TR Base;
00946
00948 typedef typename TR::Graph Graph;
00949
00950 typedef typename Graph::Node Node;
00951
00952 typedef typename Graph::NodeIt NodeIt;
00953
00954 typedef typename Graph::Edge Edge;
00955
00956 typedef typename Graph::OutEdgeIt OutEdgeIt;
00957
00960 typedef typename TR::ReachedMap ReachedMap;
00963 typedef typename TR::ProcessedMap ProcessedMap;
00966 typedef typename TR::PredMap PredMap;
00967
00968
00969
00971 typedef typename TR::DistMap DistMap;
00972
00973 public:
00975 DfsWizard() : TR() {}
00976
00978
00981 DfsWizard(const Graph &g, Node s=INVALID) :
00982 TR(g,s) {}
00983
00985 DfsWizard(const TR &b) : TR(b) {}
00986
00987 ~DfsWizard() {}
00988
00990
00993 void run()
00994 {
00995 if(Base::_source==INVALID) throw UninitializedParameter();
00996 Dfs<Graph,TR> alg(*(Graph*)Base::_g);
00997 if(Base::_reached) alg.reachedMap(*(ReachedMap*)Base::_reached);
00998 if(Base::_processed) alg.processedMap(*(ProcessedMap*)Base::_processed);
00999 if(Base::_pred) alg.predMap(*(PredMap*)Base::_pred);
01000
01001 if(Base::_dist) alg.distMap(*(DistMap*)Base::_dist);
01002 alg.run(Base::_source);
01003 }
01004
01006
01009 void run(Node s)
01010 {
01011 Base::_source=s;
01012 run();
01013 }
01014
01015 template<class T>
01016 struct DefPredMapBase : public Base {
01017 typedef T PredMap;
01018 static PredMap *createPredMap(const Graph &) { return 0; };
01019 DefPredMapBase(const TR &b) : TR(b) {}
01020 };
01021
01028 template<class T>
01029 DfsWizard<DefPredMapBase<T> > predMap(const T &t)
01030 {
01031 Base::_pred=(void *)&t;
01032 return DfsWizard<DefPredMapBase<T> >(*this);
01033 }
01034
01035
01036 template<class T>
01037 struct DefReachedMapBase : public Base {
01038 typedef T ReachedMap;
01039 static ReachedMap *createReachedMap(const Graph &) { return 0; };
01040 DefReachedMapBase(const TR &b) : TR(b) {}
01041 };
01042
01049 template<class T>
01050 DfsWizard<DefReachedMapBase<T> > reachedMap(const T &t)
01051 {
01052 Base::_pred=(void *)&t;
01053 return DfsWizard<DefReachedMapBase<T> >(*this);
01054 }
01055
01056
01057 template<class T>
01058 struct DefProcessedMapBase : public Base {
01059 typedef T ProcessedMap;
01060 static ProcessedMap *createProcessedMap(const Graph &) { return 0; };
01061 DefProcessedMapBase(const TR &b) : TR(b) {}
01062 };
01063
01070 template<class T>
01071 DfsWizard<DefProcessedMapBase<T> > processedMap(const T &t)
01072 {
01073 Base::_pred=(void *)&t;
01074 return DfsWizard<DefProcessedMapBase<T> >(*this);
01075 }
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098 template<class T>
01099 struct DefDistMapBase : public Base {
01100 typedef T DistMap;
01101 static DistMap *createDistMap(const Graph &) { return 0; };
01102 DefDistMapBase(const TR &b) : TR(b) {}
01103 };
01104
01111 template<class T>
01112 DfsWizard<DefDistMapBase<T> > distMap(const T &t)
01113 {
01114 Base::_dist=(void *)&t;
01115 return DfsWizard<DefDistMapBase<T> >(*this);
01116 }
01117
01119
01122 DfsWizard<TR> &source(Node s)
01123 {
01124 Base::_source=s;
01125 return *this;
01126 }
01127
01128 };
01129
01131
01147 template<class GR>
01148 DfsWizard<DfsWizardBase<GR> >
01149 dfs(const GR &g,typename GR::Node s=INVALID)
01150 {
01151 return DfsWizard<DfsWizardBase<GR> >(g,s);
01152 }
01153
01154 }
01155
01156 #endif
01157