00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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:
00047
00048
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
00071
00072
00073 }
00074
00075 virtual ~MyBFS()
00076 {
00077 }
00078
00079 public:
00080
00081
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
00094 visitor.startVisit(*node);
00095
00096
00097 visitor.markVisited(*node);
00098 #ifdef DEBUG
00099
00100
00101 #endif
00102 IncidentEdgeIterator inEdges = graph.incidentEdges(*node);
00103 while (inEdges.hasNext())
00104 {
00105
00106 Edge &e = *inEdges.next();
00107 if (!visitor.isVisited(e))
00108 {
00109
00110 visitor.markVisited(e);
00111
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
00119 #endif // DEBUG
00120
00121 visitor.traverseDiscovery(e, *node);
00122 nodesToVisit.push(w);
00123 visitor.markTouched(*w);
00124 }
00125 }
00126 else
00127
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
00152 virtual void startVisit(const Node& v)
00153 {}
00154
00155 virtual void finishVisit(const Node& v)
00156 {}
00157
00158 virtual void traverseDiscovery(const Edge& e, const Node& from)
00159 {}
00160
00161 virtual void traverseCross(const Edge& e, const Node& from)
00162 {}
00163
00164
00165
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
00212
00213
00214 public:
00215 unsigned int size;
00216
00217 MyComponentsBFSVisitor()
00218 {}
00219 virtual ~MyComponentsBFSVisitor()
00220 {}
00221
00222 virtual void startVisit(const Node& v)
00223 {
00224 size++;
00225 }
00226
00227 virtual void finishVisit(const Node& v)
00228 {}
00229
00230 virtual void traverseDiscovery(const Edge& e, const Node& from)
00231 {}
00232
00233 virtual void traverseCross(const Edge& e, const Node& from)
00234 {}
00235
00236
00237
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
00259 virtual void startVisit(const Node& v)
00260 {
00261 componentSize++;
00262 numUnvisitedNeighbours = 0;
00263 }
00264
00265 virtual void finishVisit(const Node& v)
00266 {
00267 if (0 == numUnvisitedNeighbours)
00268 endNodes.push_back(&v);
00269 }
00270
00271
00272 virtual void traverseDiscovery(const Edge& e, const Node& from)
00273 {
00274 numUnvisitedNeighbours++;
00275 }
00276
00277 virtual void traverseCross(const Edge& e, const Node& from)
00278 {}
00279
00280
00281
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