00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef LEMON_BFS_H
00018 #define LEMON_BFS_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 BfsDefaultTraits
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=BfsDefaultTraits<GR> >
00151 #endif
00152 class Bfs {
00153 public:
00160 class UninitializedParameter : public lemon::UninitializedParameter {
00161 public:
00162 virtual const char* exceptionName() const {
00163 return "lemon::Bfs::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::Node> _queue;
00216 int _queue_head,_queue_tail,_queue_next_dist;
00217 int _curr_dist;
00218
00219
00220
00222
00225 void create_maps()
00226 {
00227 if(!_pred) {
00228 local_pred = true;
00229 _pred = Traits::createPredMap(*G);
00230 }
00231
00232
00233
00234
00235 if(!_dist) {
00236 local_dist = true;
00237 _dist = Traits::createDistMap(*G);
00238 }
00239 if(!_reached) {
00240 local_reached = true;
00241 _reached = Traits::createReachedMap(*G);
00242 }
00243 if(!_processed) {
00244 local_processed = true;
00245 _processed = Traits::createProcessedMap(*G);
00246 }
00247 }
00248
00249 public :
00250
00252
00254
00255 template <class T>
00256 struct DefPredMapTraits : public Traits {
00257 typedef T PredMap;
00258 static PredMap *createPredMap(const Graph &G)
00259 {
00260 throw UninitializedParameter();
00261 }
00262 };
00264
00267 template <class T>
00268 class DefPredMap : public Bfs< Graph, 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 Bfs< 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 Bfs< 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 Bfs< 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 Bfs< Graph,
00358 DefGraphProcessedMapTraits> { };
00359
00361
00362 public:
00363
00365
00368 Bfs(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 ~Bfs()
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 Bfs &predMap(PredMap &m)
00395 {
00396 if(local_pred) {
00397 delete _pred;
00398 local_pred=false;
00399 }
00400 _pred = &m;
00401 return *this;
00402 }
00403
00405
00411 Bfs &reachedMap(ReachedMap &m)
00412 {
00413 if(local_reached) {
00414 delete _reached;
00415 local_reached=false;
00416 }
00417 _reached = &m;
00418 return *this;
00419 }
00420
00422
00428 Bfs &processedMap(ProcessedMap &m)
00429 {
00430 if(local_processed) {
00431 delete _processed;
00432 local_processed=false;
00433 }
00434 _processed = &m;
00435 return *this;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00456
00462 Bfs &distMap(DistMap &m)
00463 {
00464 if(local_dist) {
00465 delete _dist;
00466 local_dist=false;
00467 }
00468 _dist = &m;
00469 return *this;
00470 }
00471
00472 public:
00482
00484
00486
00489 void init()
00490 {
00491 create_maps();
00492 _queue.resize(countNodes(*G));
00493 _queue_head=_queue_tail=0;
00494 _curr_dist=1;
00495 for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
00496 _pred->set(u,INVALID);
00497
00498 _reached->set(u,false);
00499 _processed->set(u,false);
00500 }
00501 }
00502
00504
00507 void addSource(Node s)
00508 {
00509 if(!(*_reached)[s])
00510 {
00511 _reached->set(s,true);
00512 _pred->set(s,INVALID);
00513 _dist->set(s,0);
00514 _queue[_queue_head++]=s;
00515 _queue_next_dist=_queue_head;
00516 }
00517 }
00518
00520
00526 Node processNextNode()
00527 {
00528 if(_queue_tail==_queue_next_dist) {
00529 _curr_dist++;
00530 _queue_next_dist=_queue_head;
00531 }
00532 Node n=_queue[_queue_tail++];
00533 _processed->set(n,true);
00534 Node m;
00535 for(OutEdgeIt e(*G,n);e!=INVALID;++e)
00536 if(!(*_reached)[m=G->target(e)]) {
00537 _queue[_queue_head++]=m;
00538 _reached->set(m,true);
00539 _pred->set(m,e);
00540
00541 _dist->set(m,_curr_dist);
00542 }
00543 return n;
00544 }
00545
00551 bool emptyQueue() { return _queue_tail==_queue_head; }
00553
00556 int queueSize() { return _queue_head-_queue_tail; }
00557
00559
00572 void start()
00573 {
00574 while ( !emptyQueue() ) processNextNode();
00575 }
00576
00578
00591 void start(Node dest)
00592 {
00593 while ( !emptyQueue() && _queue[_queue_tail]!=dest ) processNextNode();
00594 }
00595
00597
00605 template<class NM>
00606 void start(const NM &nm)
00607 {
00608 while ( !emptyQueue() && !nm[_queue[_queue_tail]] ) processNextNode();
00609 }
00610
00612
00626 void run(Node s) {
00627 init();
00628 addSource(s);
00629 start();
00630 }
00631
00633
00645 int run(Node s,Node t) {
00646 init();
00647 addSource(s);
00648 start(t);
00649 return reached(t)?_curr_dist-1+(_queue_tail==_queue_next_dist):0;
00650 }
00651
00653
00659
00661
00663
00671 template<class P>
00672 bool getPath(P &p,Node t)
00673 {
00674 if(reached(t)) {
00675 p.clear();
00676 typename P::Builder b(p);
00677 for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t))
00678 b.pushFront(pred(t));
00679 b.commit();
00680 return true;
00681 }
00682 return false;
00683 }
00684
00686
00691 int dist(Node v) const { return (*_dist)[v]; }
00692
00694
00705 Edge pred(Node v) const { return (*_pred)[v];}
00706
00708
00719 Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
00720 G->source((*_pred)[v]); }
00721
00723
00727 const DistMap &distMap() const { return *_dist;}
00728
00730
00735 const PredMap &predMap() const { return *_pred;}
00736
00737
00738
00739
00740
00741
00742
00743
00745
00751 bool reached(Node v) { return (*_reached)[v]; }
00752
00754 };
00755
00757
00760 template<class GR>
00761 struct BfsWizardDefaultTraits
00762 {
00764 typedef GR Graph;
00772 typedef NullMap<typename Graph::Node,typename GR::Edge> PredMap;
00774
00778 #ifdef DOXYGEN
00779 static PredMap *createPredMap(const GR &g)
00780 #else
00781 static PredMap *createPredMap(const GR &)
00782 #endif
00783 {
00784 return new PredMap();
00785 }
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00805
00809 typedef NullMap<typename Graph::Node,bool> ProcessedMap;
00811
00815 #ifdef DOXYGEN
00816 static ProcessedMap *createProcessedMap(const GR &g)
00817 #else
00818 static ProcessedMap *createProcessedMap(const GR &)
00819 #endif
00820 {
00821 return new ProcessedMap();
00822 }
00824
00828 typedef typename Graph::template NodeMap<bool> ReachedMap;
00830
00834 static ReachedMap *createReachedMap(const GR &G)
00835 {
00836 return new ReachedMap(G);
00837 }
00839
00843 typedef NullMap<typename Graph::Node,int> DistMap;
00845
00848 #ifdef DOXYGEN
00849 static DistMap *createDistMap(const GR &g)
00850 #else
00851 static DistMap *createDistMap(const GR &)
00852 #endif
00853 {
00854 return new DistMap();
00855 }
00856 };
00857
00859
00866 template<class GR>
00867 class BfsWizardBase : public BfsWizardDefaultTraits<GR>
00868 {
00869
00870 typedef BfsWizardDefaultTraits<GR> Base;
00871 protected:
00873 typedef typename Base::Graph::Node Node;
00874
00876 void *_g;
00878 void *_reached;
00880 void *_processed;
00882 void *_pred;
00883
00884
00886 void *_dist;
00888 Node _source;
00889
00890 public:
00892
00895 BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
00896
00897 _dist(0), _source(INVALID) {}
00898
00900
00906 BfsWizardBase(const GR &g, Node s=INVALID) :
00907 _g((void *)&g), _reached(0), _processed(0), _pred(0),
00908
00909 _dist(0), _source(s) {}
00910
00911 };
00912
00914
00932 template<class TR>
00933 class BfsWizard : public TR
00934 {
00935 typedef TR Base;
00936
00938 typedef typename TR::Graph Graph;
00939
00940 typedef typename Graph::Node Node;
00941
00942 typedef typename Graph::NodeIt NodeIt;
00943
00944 typedef typename Graph::Edge Edge;
00945
00946 typedef typename Graph::OutEdgeIt OutEdgeIt;
00947
00950 typedef typename TR::ReachedMap ReachedMap;
00953 typedef typename TR::ProcessedMap ProcessedMap;
00956 typedef typename TR::PredMap PredMap;
00957
00958
00959
00961 typedef typename TR::DistMap DistMap;
00962
00963 public:
00965 BfsWizard() : TR() {}
00966
00968
00971 BfsWizard(const Graph &g, Node s=INVALID) :
00972 TR(g,s) {}
00973
00975 BfsWizard(const TR &b) : TR(b) {}
00976
00977 ~BfsWizard() {}
00978
00980
00983 void run()
00984 {
00985 if(Base::_source==INVALID) throw UninitializedParameter();
00986 Bfs<Graph,TR> alg(*(Graph*)Base::_g);
00987 if(Base::_reached)
00988 alg.reachedMap(*(ReachedMap*)Base::_reached);
00989 if(Base::_processed) alg.processedMap(*(ProcessedMap*)Base::_processed);
00990 if(Base::_pred) alg.predMap(*(PredMap*)Base::_pred);
00991
00992 if(Base::_dist) alg.distMap(*(DistMap*)Base::_dist);
00993 alg.run(Base::_source);
00994 }
00995
00997
01000 void run(Node s)
01001 {
01002 Base::_source=s;
01003 run();
01004 }
01005
01006 template<class T>
01007 struct DefPredMapBase : public Base {
01008 typedef T PredMap;
01009 static PredMap *createPredMap(const Graph &) { return 0; };
01010 DefPredMapBase(const TR &b) : TR(b) {}
01011 };
01012
01019 template<class T>
01020 BfsWizard<DefPredMapBase<T> > predMap(const T &t)
01021 {
01022 Base::_pred=(void *)&t;
01023 return BfsWizard<DefPredMapBase<T> >(*this);
01024 }
01025
01026
01027 template<class T>
01028 struct DefReachedMapBase : public Base {
01029 typedef T ReachedMap;
01030 static ReachedMap *createReachedMap(const Graph &) { return 0; };
01031 DefReachedMapBase(const TR &b) : TR(b) {}
01032 };
01033
01040 template<class T>
01041 BfsWizard<DefReachedMapBase<T> > reachedMap(const T &t)
01042 {
01043 Base::_pred=(void *)&t;
01044 return BfsWizard<DefReachedMapBase<T> >(*this);
01045 }
01046
01047
01048 template<class T>
01049 struct DefProcessedMapBase : public Base {
01050 typedef T ProcessedMap;
01051 static ProcessedMap *createProcessedMap(const Graph &) { return 0; };
01052 DefProcessedMapBase(const TR &b) : TR(b) {}
01053 };
01054
01061 template<class T>
01062 BfsWizard<DefProcessedMapBase<T> > processedMap(const T &t)
01063 {
01064 Base::_pred=(void *)&t;
01065 return BfsWizard<DefProcessedMapBase<T> >(*this);
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089 template<class T>
01090 struct DefDistMapBase : public Base {
01091 typedef T DistMap;
01092 static DistMap *createDistMap(const Graph &) { return 0; };
01093 DefDistMapBase(const TR &b) : TR(b) {}
01094 };
01095
01102 template<class T>
01103 BfsWizard<DefDistMapBase<T> > distMap(const T &t)
01104 {
01105 Base::_dist=(void *)&t;
01106 return BfsWizard<DefDistMapBase<T> >(*this);
01107 }
01108
01110
01113 BfsWizard<TR> &source(Node s)
01114 {
01115 Base::_source=s;
01116 return *this;
01117 }
01118
01119 };
01120
01122
01138 template<class GR>
01139 BfsWizard<BfsWizardBase<GR> >
01140 bfs(const GR &g,typename GR::Node s=INVALID)
01141 {
01142 return BfsWizard<BfsWizardBase<GR> >(g,s);
01143 }
01144
01145 }
01146
01147 #endif
01148