2 #ifndef HUGO_BFS_ITERATOR_H
3 #define HUGO_BFS_ITERATOR_H
11 template <typename Graph, /*typename OutEdgeIt,*/
12 typename ReachedMap/*=typename Graph::NodeMap<bool>*/ >
15 typedef typename Graph::Node Node;
16 typedef typename Graph::OutEdgeIt OutEdgeIt;
18 std::queue<Node> bfs_queue;
20 bool b_node_newly_reached;
21 OutEdgeIt actual_edge;
24 BfsIterator(const Graph& _graph, ReachedMap& _reached) :
25 graph(&_graph), reached(_reached),
26 own_reached_map(false) { }
27 BfsIterator(const Graph& _graph) :
28 graph(&_graph), reached(*(new ReachedMap(*graph /*, false*/))),
29 own_reached_map(true) { }
30 ~BfsIterator() { if (own_reached_map) delete &reached; }
31 //s is marcked reached.
32 //if the queue is empty, then the its is pushed ant the first OutEdgeIt is processe.
33 //is the queue is not empty, then is it pushed.
34 void pushAndSetReached(Node s) {
36 if (bfs_queue.empty()) {
38 graph->first(actual_edge, s);
39 if (graph->valid(actual_edge)) {
40 Node w=graph->bNode(actual_edge);
44 b_node_newly_reached=true;
46 b_node_newly_reached=false;
53 BfsIterator<Graph, /*OutEdgeIt,*/ ReachedMap>&
55 if (graph->valid(actual_edge)) {
56 graph->next(actual_edge);
57 if (graph->valid(actual_edge)) {
58 Node w=graph->bNode(actual_edge);
62 b_node_newly_reached=true;
64 b_node_newly_reached=false;
69 if (!bfs_queue.empty()) {
70 graph->first(actual_edge, bfs_queue.front());
71 if (graph->valid(actual_edge)) {
72 Node w=graph->bNode(actual_edge);
76 b_node_newly_reached=true;
78 b_node_newly_reached=false;
85 bool finished() const { return bfs_queue.empty(); }
86 operator OutEdgeIt() const { return actual_edge; }
87 bool isBNodeNewlyReached() const { return b_node_newly_reached; }
88 bool isANodeExamined() const { return !(graph->valid(actual_edge)); }
89 Node aNode() const { return bfs_queue.front(); }
90 Node bNode() const { return graph->bNode(actual_edge); }
91 const ReachedMap& getReachedMap() const { return reached; }
92 const std::queue<Node>& getBfsQueue() const { return bfs_queue; }
95 /// Bfs searches from s for the nodes wich are not marked in
97 template <typename Graph,
98 typename ReachedMap=typename Graph::template NodeMap<bool>,
100 =typename Graph::template NodeMap<typename Graph::Edge>,
101 typename DistMap=typename Graph::template NodeMap<int> >
102 class Bfs : public BfsIterator<Graph, ReachedMap> {
103 typedef BfsIterator<Graph, ReachedMap> Parent;
105 typedef typename Parent::Node Node;
109 Bfs<Graph, ReachedMap, PredMap, DistMap>(const Graph& _graph, ReachedMap& _reached, PredMap& _pred, DistMap& _dist) : BfsIterator<Graph, ReachedMap>(_graph, _reached), pred(&_pred), dist(&_dist) { }
110 //s is marked to be reached and pushed in the bfs queue.
111 //if the queue is empty, then the first out-edge is processed
112 //If s was not marked previously, then
113 //in addition its pred is set to be INVALID, and dist to 0.
114 //if s was marked previuosly, then it is simply pushed.
116 if (this->reached[s]) {
117 Parent::pushAndSetReached(s);
119 Parent::pushAndSetReached(s);
120 pred.set(s, INVALID);
126 while (!this->finished()) this->operator++();
128 Bfs<Graph, ReachedMap, PredMap, DistMap> operator++() {
129 Parent::operator++();
130 if (this->graph->valid(this->actual_edge) && this->b_node_newly_reached)
132 pred.set(this->bNode(), this->actual_edge);
133 dist.set(this->bNode(), dist[this->aNode()]);
137 const PredMap& getPredMap() const { return pred; }
138 const DistMap& getDistMap() const { return dist; }
141 template <typename Graph, /*typename OutEdgeIt,*/
142 typename ReachedMap/*=typename Graph::NodeMap<bool>*/ >
145 typedef typename Graph::Node Node;
146 typedef typename Graph::OutEdgeIt OutEdgeIt;
148 std::stack<OutEdgeIt> dfs_stack;
149 bool b_node_newly_reached;
150 OutEdgeIt actual_edge;
153 bool own_reached_map;
155 DfsIterator(const Graph& _graph, ReachedMap& _reached) :
156 graph(&_graph), reached(_reached),
157 own_reached_map(false) { }
158 DfsIterator(const Graph& _graph) :
159 graph(&_graph), reached(*(new ReachedMap(*graph /*, false*/))),
160 own_reached_map(true) { }
161 ~DfsIterator() { if (own_reached_map) delete &reached; }
162 void pushAndSetReached(Node s) {
164 reached.set(s, true);
169 DfsIterator<Graph, /*OutEdgeIt,*/ ReachedMap>&
171 actual_edge=dfs_stack.top();
172 //actual_node=G.aNode(actual_edge);
173 if (graph->valid(actual_edge)/*.valid()*/) {
174 Node w=graph->bNode(actual_edge);
180 reached.set(w, true);
181 b_node_newly_reached=true;
183 actual_node=graph->aNode(actual_edge);
184 graph->next(dfs_stack.top());
185 b_node_newly_reached=false;
188 //actual_node=G.aNode(dfs_stack.top());
193 bool finished() const { return dfs_stack.empty(); }
194 operator OutEdgeIt() const { return actual_edge; }
195 bool isBNodeNewlyReached() const { return b_node_newly_reached; }
196 bool isANodeExamined() const { return !(graph->valid(actual_edge)); }
197 Node aNode() const { return actual_node; /*FIXME*/}
198 Node bNode() const { return graph->bNode(actual_edge); }
199 const ReachedMap& getReachedMap() const { return reached; }
200 const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; }
205 #endif //HUGO_BFS_ITERATOR_H