Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

dfs.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  * lemon/dfs.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Research Group on Combinatorial Optimization, 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_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 //     ///\brief The type of the map that stores the last but one
00061 //     ///nodes of the %DFS paths.
00062 //     ///
00063 //     ///The type of the map that stores the last but one
00064 //     ///nodes of the %DFS paths.
00065 //     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
00066 //     ///
00067 //     typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
00068 //     ///Instantiates a PredNodeMap.
00069     
00070 //     ///This function instantiates a \ref PredNodeMap. 
00071 //     ///\param G is the graph, to which
00072 //     ///we would like to define the \ref PredNodeMap
00073 //     static PredNodeMap *createPredNodeMap(const GR &G)
00074 //     {
00075 //       return new PredNodeMap();
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 //     ///\brief The type of the map that stores the last but one
00183 //     ///nodes of the %DFS paths.
00184 //     typedef typename TR::PredNodeMap PredNodeMap;
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 //     ///Pointer to the map of predecessors nodes.
00199 //     PredNodeMap *_predNode;
00200 //     ///Indicates if \ref _predNode is locally allocated (\c true) or not.
00201 //     bool local_predNode;
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 //     ///The source node of the last execution.
00218 //     Node source;
00219 
00221     
00224     void create_maps() 
00225     {
00226       if(!_pred) {
00227         local_pred = true;
00228         _pred = Traits::createPredMap(*G);
00229       }
00230 //       if(!_predNode) {
00231 //      local_predNode = true;
00232 //      _predNode = Traits::createPredNodeMap(*G);
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 //     template <class T>
00271 //     struct DefPredNodeMapTraits : public Traits {
00272 //       typedef T PredNodeMap;
00273 //       static PredNodeMap *createPredNodeMap(const Graph &G) 
00274 //       {
00275 //      throw UninitializedParameter();
00276 //       }
00277 //     };
00278 //     ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
00279 
00280 //     ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
00281 //     ///
00282 //     template <class T>
00283 //     class DefPredNodeMap : public Dfs< Graph,
00284 //                                          LengthMap,
00285 //                                          DefPredNodeMapTraits<T> > { };
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 //       _predNode(NULL), local_predNode(false),
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 //       if(local_predNode) delete _predNode;
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 //     ///Sets the map storing the predecessor nodes.
00405 
00406 //     ///Sets the map storing the predecessor nodes.
00407 //     ///If you don't use this function before calling \ref run(),
00408 //     ///it will allocate one. The destuctor deallocates this
00409 //     ///automatically allocated map, of course.
00410 //     ///\return <tt> (*this) </tt>
00411 //     Dfs &predNodeMap(PredNodeMap &m) 
00412 //     {
00413 //       if(local_predNode) {
00414 //      delete _predNode;
00415 //      local_predNode=false;
00416 //       }
00417 //       _predNode = &m;
00418 //       return *this;
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         // _predNode->set(u,INVALID);
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           // _predNode->set(u,INVALID);
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         //        _pred_node->set(m,G->source(e));
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 //     ///Returns a reference to the map of nodes of %DFS paths.
00748 
00749 //     ///Returns a reference to the NodeMap of the last but one nodes of the
00750 //     ///%DFS tree.
00751 //     ///\pre \ref run() must be called before using this function.
00752 //     const PredNodeMap &predNodeMap() const { return *_predNode;}
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 //     ///\brief The type of the map that stores the last but one
00797 //     ///nodes of the %DFS paths.
00798 //     ///
00799 //     ///The type of the map that stores the last but one
00800 //     ///nodes of the %DFS paths.
00801 //     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
00802 //     ///
00803 //     typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
00804 //     ///Instantiates a PredNodeMap.
00805     
00806 //     ///This function instantiates a \ref PredNodeMap. 
00807 //     ///\param G is the graph, to which
00808 //     ///we would like to define the \ref PredNodeMap
00809 //     static PredNodeMap *createPredNodeMap(const GR &G)
00810 //     {
00811 //       return new PredNodeMap();
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 //     ///Pointer to the map of predecessors nodes.
00894 //     void *_predNode;
00896     void *_dist;
00898     Node _source;
00899     
00900     public:
00902     
00905     DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
00906 //                         _predNode(0),
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 //       _predNode(0),
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     //\e
00950     typedef typename Graph::Node Node;
00951     //\e
00952     typedef typename Graph::NodeIt NodeIt;
00953     //\e
00954     typedef typename Graph::Edge Edge;
00955     //\e
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 //     ///\brief The type of the map that stores the last but one
00968 //     ///nodes of the %DFS paths.
00969 //     typedef typename TR::PredNodeMap PredNodeMap;
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 //       if(Base::_predNode) alg.predNodeMap(*(PredNodeMap*)Base::_predNode);
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 //     template<class T>
01079 //     struct DefPredNodeMapBase : public Base {
01080 //       typedef T PredNodeMap;
01081 //       static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
01082 //       DefPredNodeMapBase(const TR &b) : TR(b) {}
01083 //     };
01084     
01085 //     ///\brief \ref named-templ-param "Named parameter"
01086 //     ///function for setting PredNodeMap type
01087 //     ///
01088 //     /// \ref named-templ-param "Named parameter"
01089 //     ///function for setting PredNodeMap type
01090 //     ///
01091 //     template<class T>
01092 //     DfsWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t) 
01093 //     {
01094 //       Base::_predNode=(void *)&t;
01095 //       return DfsWizard<DefPredNodeMapBase<T> >(*this);
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 } //END OF NAMESPACE LEMON
01155 
01156 #endif
01157 

Generated on Sat Aug 27 14:14:51 2005 for LEMON by  doxygen 1.4.4