Biorithm  1.1
 All Classes Functions Variables Typedefs Friends
dfs.h
00001 /**************************************************************************
00002  * Copyright (c) 2002-2011 T. M. Murali                                   *
00003  * Copyright (c) 2005 Shivaram Narayanan                                  *
00004  *                                                                        *
00005  * This file is part of Biorithm.                                         *
00006  *                                                                        *
00007  * Biorithm is free software: you can redistribute it and/or modify       *
00008  * it under the terms of the GNU General Public License as published by   *
00009  * the Free Software Foundation, either version 3 of the License, or      *
00010  * (at your option) any later version.                                    *
00011  *                                                                        *
00012  * Biorithm is distributed in the hope that it will be useful,            *
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of         *
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
00015  * GNU General Public License for more details.                           *
00016  *                                                                        *
00017  * You should have received a copy of the GNU General Public License      *
00018  * along with Biorithm.  If not, see <http://www.gnu.org/licenses/>.      *
00019  *                                                                        *
00020  **************************************************************************/
00027 #ifndef _DFS_H
00028 #define _DFS_H
00029 
00030 #include "graph.h"
00031 
00032 template <typename Graph, typename DFSVisitor>
00033 class MyDFS {
00034 protected:
00035   typedef typename Graph::Node      Node;
00036   typedef typename Graph::Edge              Edge;
00037   typedef typename Graph::NodeIterator    NodeIterator;
00038   typedef typename Graph::IncidentEdgeIterator      EdgeIterator;
00039 protected:                                              // member data
00040 
00041   // the graph to be traversed
00042   Graph& graph;
00043   DFSVisitor &visitor;
00044   
00045 public:
00046   MyDFS(Graph& g, DFSVisitor &v) 
00047       : graph(g), visitor(v)
00048     {}
00049 
00050   void initialise() 
00051   {                                     
00052     NodeIterator nitr = graph.nodes();          
00053     while (nitr.hasNext())
00054       {
00055         Node &node = nitr.next();
00056         visitor.markUnvisited(node);
00057         EdgeIterator eitr = graph.incidentEdges(node);
00058         while (eitr.hasNext())
00059           visitor.markUnvisited(*eitr.next());
00060       }
00061     
00062 //     eitr = graph.edges();
00063 //     while (eitr.hasNext())
00064 //       visitor.markUnvisited(eitr.next());
00065   }
00066   
00067   virtual ~MyDFS()
00068     { 
00069     }
00070 
00071 public:                                         
00072 
00073   // perform the traversal
00074   void traverse(Node& v) 
00075   {     
00076 #ifdef DEBUG
00077     // MyGraph::MyNodeIterator itr1 = graph.nodes();
00078     // cout << "\tVisited status before traversal starting at node " << v.getId()
00079     //      << "(" << &v << "): ";
00080     // while (itr1.hasNext())
00081     //   {
00082     //     MyNode &node1 = itr1.next();
00083     //     cout << "(" << node1.getId() << ", "
00084     //          << node1.getStatus("visited") << ") ";
00085     //   }
00086     // cout << endl;
00087 #endif          
00088     // visit v.
00089     visitor.startVisit(v);
00090     // mark v as being visited.
00091     visitor.markVisited(v);
00092 #ifdef DEBUG
00093     // cout << "\tIn traverse(): node " << v.getId()
00094     //      << " (" << &v << ")"
00095     //      << " has degree " << v.degree() << endl;
00096 #endif    
00097     EdgeIterator inEdges = graph.incidentEdges(v);
00098     while (inEdges.hasNext()) 
00099       {                         // try all its edges
00100         Edge &e = *inEdges.next();
00101         if (!visitor.isVisited(e)) 
00102           {
00103             // mark the new edge visited
00104             visitor.markVisited(e);
00105             // get next vertex
00106             Node *w = e.opposite(v);
00107 #ifdef DEBUG
00108              // cout << "\tDuring traversal, visited status of node " << w->getId()
00109              //      << " (" << &w << ")"
00110              //      << " is " << visitor.isVisited(*w) << endl;
00111 #endif            
00112             if (!visitor.isVisited(*w)) 
00113               {
00114                 // unexplored edge. discover it.
00115                 visitor.traverseDiscovery(e, v);
00116                 // isDone() checks whether we should visit *w or not.
00117                 if (!visitor.isDone(e, v, *w))
00118                   // continue traversal
00119                   traverse(*w);                         
00120               }
00121             else                                                // explored
00122               visitor.traverseBack(e, v);                               // process back edge
00123           }
00124       }
00125     visitor.finishVisit(v);                                     // all done
00126 #ifdef DEBUG
00127     // MyGraph::MyNodeIterator itr1 = nodes();
00128     // cout << "\tVisited status after traversal starting at node " << v.getId()
00129     //      << ": ";
00130     // itr1 = graph.nodes();
00131     // while (itr1.hasNext())
00132     //   {
00133     //     MyNode &node1 = itr1.next();
00134     //     cout << "(" << node1.getId() << ", "
00135     //          << node1.getStatus("visited") << ") ";
00136     //   }
00137     // cout << endl;
00138 #endif          
00139   }
00140 };
00141 
00142 
00143 class  MyDefaultDFSVisitor
00144 {
00145 public:
00146 
00147   typedef MyNode            Node;
00148   typedef MyEdge                    Edge;
00149   
00150   MyDefaultDFSVisitor()
00151     {}
00152   virtual ~MyDefaultDFSVisitor()
00153     {}
00154   virtual void initialise()
00155     {}
00156   
00157   // what do i when i visit v first?
00158   virtual void startVisit(const Node& v) 
00159   {}
00160   // finished with v
00161   virtual void finishVisit(const Node& v) 
00162   {}
00163   // discover edge e
00164   virtual void traverseDiscovery(const Edge& e, const Node& from) 
00165   {}
00166   // back edge e
00167   virtual void traverseBack(const Edge& e, const Node& from) 
00168   {}
00169   
00170 
00171   // done early?  
00172   virtual bool isDone(const Edge& e, const Node& from, const Node &to) const
00173     {
00174       return false;
00175     }           
00176 
00177   void markVisited(Node& v)
00178   { 
00179 #ifdef DEBUG
00180 //    cout << "\tMarking node " << v.getId() << " as visited." << endl;
00181 #endif    
00182     v.setStatus("visited");
00183   }
00184   void markVisited(Edge& e)
00185   { 
00186 #ifdef DEBUG
00187 //      cout << "\tMarking edge connecting " << e.head().getId() << " and "
00188 //           << e.tail().getId() << " as visited." << endl;
00189 #endif    
00190     e.setStatus("visited");
00191   }
00192   void markUnvisited(Node& v)
00193   { 
00194 #ifdef DEBUG
00195 //    cout << "\tMarking node " << v.getId() << " as unvisited." << endl;
00196 #endif    
00197     v.clearStatus("visited");
00198   }
00199   void markUnvisited(Edge& e)
00200   { 
00201 #ifdef DEBUG
00202 //      cout << "\tMarking edge connecting " << e.head().getId() << " and "
00203 //           << e.tail().getId() << " as unvisited." << endl;
00204 #endif    
00205     e.clearStatus("visited");
00206   }
00207   bool isVisited(Node& v)
00208   { 
00209     return v.getStatus("visited");
00210   }
00211   bool isVisited(Edge& e)
00212   { 
00213     return e.getStatus("visited");
00214   }
00215 };
00216 
00217 class  MyComponentsDFSVisitor: public MyDefaultDFSVisitor
00218 {
00219 private:
00220   //vector< MyGraph > components;
00221 //  vector< unsigned int > componentSizes;
00222 
00223 //  const MyEdge *lastEdge;
00224   MyGraph component;
00225   unsigned int size;
00226 public:
00227   
00228   MyComponentsDFSVisitor()
00229       : //lastEdge(NULL),
00230         component(), size(0)
00231     {}
00232   virtual ~MyComponentsDFSVisitor()
00233     {}
00234 
00235   virtual void initialise()
00236     {
00237       component.clear();
00238       size = 0;
00239     }
00240   
00241   // what do i when i visit v first?
00242   virtual void startVisit(const Node& v) 
00243   {
00244     component.addNode(v);
00245     size++;
00246   }
00247   // finished with v
00248   virtual void finishVisit(const Node& v) 
00249   {}
00250   // discover edge e
00251   virtual void traverseDiscovery(const Edge& e, const Node& from) 
00252   {
00253     // add the new node and the new edge.
00254     MyNode &other = *(e.opposite(from));
00255     component.addNode(other);
00256     component.addEdge(e);
00257   }
00258   // back edge e
00259   virtual void traverseBack(const Edge& e, const Node& from) 
00260   {
00261     component.addEdge(e);
00262   }
00263   
00264 
00265   virtual MyGraph &getComponent()
00266     {
00267       return(component);
00268     }
00269   
00270   virtual unsigned int getSize()
00271     {
00272       return(size);
00273     }
00274   
00275 };
00276 
00277 #endif // _DFS_H 
 All Classes Functions Variables Typedefs Friends