Biorithm  1.1
 All Classes Functions Variables Typedefs Friends
bfs.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  **************************************************************************/
00021 
00028 #ifndef _BFS_H
00029 #define _BFS_H
00030 
00031 #include <queue>
00032 
00033 #include "graph.h"
00034 
00035 
00036 
00037 
00038 template <typename Graph, typename BFSVisitor>
00039 class MyBFS {
00040 protected:
00041   typedef typename Graph::Node      Node;
00042   typedef typename Graph::Edge              Edge;
00043   typedef typename Graph::NodeIterator    NodeIterator;
00044   typedef typename Graph::EdgeIterator      EdgeIterator;
00045   typedef typename Graph::IncidentEdgeIterator      IncidentEdgeIterator;
00046 protected:                                              // member data
00047 
00048   // the graph to be traversed
00049   Graph& graph;
00050   BFSVisitor &visitor;
00051   
00052 public:
00053   MyBFS(Graph& g, BFSVisitor &v) 
00054       : graph(g), visitor(v)
00055     {}
00056 
00057   void initialise() 
00058   {                                     
00059     NodeIterator nitr = graph.nodes();          
00060     while (nitr.hasNext())
00061       {
00062         Node &node = nitr.next();
00063         visitor.markUnvisited(node);
00064         visitor.markUntouched(node);
00065         IncidentEdgeIterator eitr = graph.incidentEdges(node);
00066         while (eitr.hasNext())
00067           visitor.markUnvisited(*eitr.next());
00068       }
00069     
00070 //     eitr = graph.edges();
00071 //     while (eitr.hasNext())
00072 //       visitor.markUnvisited(eitr.next());
00073   }
00074   
00075   virtual ~MyBFS()
00076     { 
00077     }
00078 
00079 public:                                         
00080 
00081   // perform the traversal
00082   void traverse(Node& v) 
00083   {
00084     queue< Node* > nodesToVisit;
00085     nodesToVisit.push(&v);
00086     visitor.markTouched(v);
00087     Node *node;
00088     
00089     while (!nodesToVisit.empty())
00090       {
00091         node = nodesToVisit.front();
00092         nodesToVisit.pop();
00093         // visit node.
00094         visitor.startVisit(*node);
00095     
00096         // mark node as being visited.
00097         visitor.markVisited(*node);
00098 #ifdef DEBUG
00099 //          cout << "\tNode " << node->getId() << " has degree "
00100 //               << node->degree() << endl;
00101 #endif    
00102         IncidentEdgeIterator inEdges = graph.incidentEdges(*node);
00103         while (inEdges.hasNext()) 
00104           {
00105             // try all the edges incident on *node.
00106             Edge &e = *inEdges.next();
00107             if (!visitor.isVisited(e)) 
00108               {
00109                 // mark the new edge visited
00110                 visitor.markVisited(e);
00111                 // get next vertex
00112                 Node *w = e.opposite(*node);
00113                 if (!visitor.isVisited(*w) && !visitor.isTouched(*w)) 
00114                   {
00115                     if (!visitor.isDone(e, *node, *w))
00116                       {
00117 #ifdef DEBUG
00118 //                        cout << "Pushing node " << w.getId() << endl;
00119 #endif // DEBUG
00120                         // unexplored edge. discover it.
00121                         visitor.traverseDiscovery(e, *node);
00122                         nodesToVisit.push(w);
00123                         visitor.markTouched(*w);
00124                       }
00125                   }
00126                 else
00127                   // process cross edge
00128                   visitor.traverseCross(e, *node);
00129               }
00130           }
00131         visitor.finishVisit(*node);
00132       }
00133     
00134   }
00135 };
00136 
00137 
00138 class  MyDefaultBFSVisitor
00139 {
00140 public:
00141 
00142   typedef MyNode            Node;
00143   typedef MyEdge                    Edge;
00144 
00145   MyDefaultBFSVisitor()
00146     {}
00147   virtual ~MyDefaultBFSVisitor()
00148     {}
00149   
00150 
00151   // what do i when i visit v first?
00152   virtual void startVisit(const Node& v) 
00153   {}
00154   // finished with v
00155   virtual void finishVisit(const Node& v) 
00156   {}
00157   // discover edge e
00158   virtual void traverseDiscovery(const Edge& e, const Node& from) 
00159   {}
00160   // cross edge e
00161   virtual void traverseCross(const Edge& e, const Node& from) 
00162   {}
00163   
00164 
00165   // done early?  
00166   virtual bool isDone(const Edge& e, const Node& from, const Node &to) const
00167     { return false; }           
00168 
00169   void markTouched(Node& v)
00170   { 
00171     v.setStatus("touched");
00172   }
00173   void markUntouched(Node& v)
00174   { 
00175     v.clearStatus("touched");
00176   }
00177 
00178   void markVisited(Node& v)
00179   { 
00180     v.setStatus("visited");
00181   }
00182   void markVisited(Edge& e)
00183   { 
00184     e.setStatus("visited");
00185   }
00186   void markUnvisited(Node& v)
00187   { 
00188     v.clearStatus("visited");
00189   }
00190   void markUnvisited(Edge& e)
00191   { 
00192     e.clearStatus("visited");
00193   }
00194   bool isTouched(Node& v)
00195   { 
00196     return v.getStatus("touched");
00197   }
00198   bool isVisited(Node& v)
00199   { 
00200     return v.getStatus("visited");
00201   }
00202   bool isVisited(Edge& e)
00203   { 
00204     return e.getStatus("visited");
00205   }
00206 };
00207 
00208 class  MyComponentsBFSVisitor: public MyDefaultBFSVisitor
00209 {
00210 private:
00211   //vector< MyGraph > components;
00212 //  vector< unsigned int > componentSizes;
00213   
00214 public:
00215   unsigned int size;
00216   
00217   MyComponentsBFSVisitor()
00218     {}
00219   virtual ~MyComponentsBFSVisitor()
00220     {}
00221   // what do i when i visit v first?
00222   virtual void startVisit(const Node& v) 
00223   {
00224     size++;
00225   }
00226   // finished with v
00227   virtual void finishVisit(const Node& v) 
00228   {}
00229   // discovery edge e
00230   virtual void traverseDiscovery(const Edge& e, const Node& from) 
00231   {}
00232   // cross edge e
00233   virtual void traverseCross(const Edge& e, const Node& from) 
00234   {}
00235   
00236 
00237   // done early?  
00238   virtual bool isDone(const Edge& e, const Node& from, const Node &to) const
00239     { return false; }           
00240 
00241 };
00242 
00243 
00244 class  MyEndsBFSVisitor: public MyDefaultBFSVisitor
00245 {
00246 private:
00247   
00248 public:
00249   unsigned int numUnvisitedNeighbours;
00250   vector< const Node* > endNodes;
00251   unsigned int componentSize;
00252   
00253   MyEndsBFSVisitor()
00254     {}
00255   virtual ~MyEndsBFSVisitor()
00256     {}
00257 
00258   // what do i when i visit v first?
00259   virtual void startVisit(const Node& v) 
00260   {
00261     componentSize++;
00262     numUnvisitedNeighbours = 0;
00263   }
00264   // finished with v
00265   virtual void finishVisit(const Node& v) 
00266   {
00267     if (0 == numUnvisitedNeighbours)
00268       endNodes.push_back(&v);
00269   }
00270   
00271   // discovery edge e
00272   virtual void traverseDiscovery(const Edge& e, const Node& from) 
00273   {
00274     numUnvisitedNeighbours++;
00275   }
00276   // cross edge e
00277   virtual void traverseCross(const Edge& e, const Node& from) 
00278   {}
00279   
00280 
00281   // done early?  
00282   virtual bool isDone(const Edge& e, const Node& from, const Node &to) const
00283     { return false; }           
00284 
00285 };
00286 
00287 
00288 
00289 #endif // _BFS_H 
 All Classes Functions Variables Typedefs Friends