2 #ifndef HUGO_BFS_ITERATOR_H
3 #define HUGO_BFS_ITERATOR_H
9 #include <hugo/invalid.h>
13 template <typename Graph, /*typename OutEdgeIt,*/
14 typename ReachedMap/*=typename Graph::NodeMap<bool>*/ >
17 typedef typename Graph::Node Node;
18 typedef typename Graph::OutEdgeIt OutEdgeIt;
20 std::queue<Node> bfs_queue;
22 bool b_node_newly_reached;
23 OutEdgeIt actual_edge;
26 BfsIterator(const Graph& _graph, ReachedMap& _reached) :
27 graph(&_graph), reached(_reached),
28 own_reached_map(false) { }
29 BfsIterator(const Graph& _graph) :
30 graph(&_graph), reached(*(new ReachedMap(*graph /*, false*/))),
31 own_reached_map(true) { }
32 ~BfsIterator() { if (own_reached_map) delete &reached; }
33 /// This method markes s reached.
34 /// If the queue is empty, then s is pushed in the bfs queue
35 /// and the first OutEdgeIt is processed.
36 /// If the queue is not empty, then s is simply pushed.
37 void pushAndSetReached(Node s) {
39 if (bfs_queue.empty()) {
41 graph->first(actual_edge, s);
42 if (graph->valid(actual_edge)) {
43 Node w=graph->bNode(actual_edge);
47 b_node_newly_reached=true;
49 b_node_newly_reached=false;
56 /// As \c BfsIterator<Graph, ReachedMap> works as an edge-iterator,
57 /// its \c operator++() iterates on the edges in a bfs order.
58 BfsIterator<Graph, /*OutEdgeIt,*/ ReachedMap>&
60 if (graph->valid(actual_edge)) {
61 graph->next(actual_edge);
62 if (graph->valid(actual_edge)) {
63 Node w=graph->bNode(actual_edge);
67 b_node_newly_reached=true;
69 b_node_newly_reached=false;
74 if (!bfs_queue.empty()) {
75 graph->first(actual_edge, bfs_queue.front());
76 if (graph->valid(actual_edge)) {
77 Node w=graph->bNode(actual_edge);
81 b_node_newly_reached=true;
83 b_node_newly_reached=false;
90 bool finished() const { return bfs_queue.empty(); }
91 /// The conversion operator makes for converting the bfs-iterator
92 /// to an \c out-edge-iterator.
93 operator OutEdgeIt() const { return actual_edge; }
94 bool isBNodeNewlyReached() const { return b_node_newly_reached; }
95 bool isANodeExamined() const { return !(graph->valid(actual_edge)); }
96 Node aNode() const { return bfs_queue.front(); }
97 Node bNode() const { return graph->bNode(actual_edge); }
98 const ReachedMap& getReachedMap() const { return reached; }
99 const std::queue<Node>& getBfsQueue() const { return bfs_queue; }
102 /// Bfs searches from s for the nodes wich are not marked in
104 /// Reached is a read-write bool-map, Pred is a write-nodemap
105 /// and dist is an rw-nodemap, have to be.
106 template <typename Graph,
107 typename ReachedMap=typename Graph::template NodeMap<bool>,
109 =typename Graph::template NodeMap<typename Graph::Edge>,
110 typename DistMap=typename Graph::template NodeMap<int> >
111 class Bfs : public BfsIterator<Graph, ReachedMap> {
112 typedef BfsIterator<Graph, ReachedMap> Parent;
114 typedef typename Parent::Node Node;
118 Bfs<Graph, ReachedMap, PredMap, DistMap>(const Graph& _graph, ReachedMap& _reached, PredMap& _pred, DistMap& _dist) : BfsIterator<Graph, ReachedMap>(_graph, _reached), pred(&_pred), dist(&_dist) { }
119 /// s is marked to be reached and pushed in the bfs queue.
120 /// If the queue is empty, then the first out-edge is processed.
121 /// If s was not marked previously, then
122 /// in addition its pred is set to be INVALID, and dist to 0.
123 /// if s was marked previuosly, then it is simply pushed.
125 if (this->reached[s]) {
126 Parent::pushAndSetReached(s);
128 Parent::pushAndSetReached(s);
129 pred.set(s, INVALID);
133 /// A bfs is processed from s.
136 while (!this->finished()) this->operator++();
138 Bfs<Graph, ReachedMap, PredMap, DistMap> operator++() {
139 Parent::operator++();
140 if (this->graph->valid(this->actual_edge) && this->b_node_newly_reached)
142 pred.set(this->bNode(), this->actual_edge);
143 dist.set(this->bNode(), dist[this->aNode()]);
147 const PredMap& getPredMap() const { return pred; }
148 const DistMap& getDistMap() const { return dist; }
151 template <typename Graph, /*typename OutEdgeIt,*/
152 typename ReachedMap/*=typename Graph::NodeMap<bool>*/ >
155 typedef typename Graph::Node Node;
156 typedef typename Graph::OutEdgeIt OutEdgeIt;
158 std::stack<OutEdgeIt> dfs_stack;
159 bool b_node_newly_reached;
160 OutEdgeIt actual_edge;
163 bool own_reached_map;
165 DfsIterator(const Graph& _graph, ReachedMap& _reached) :
166 graph(&_graph), reached(_reached),
167 own_reached_map(false) { }
168 DfsIterator(const Graph& _graph) :
169 graph(&_graph), reached(*(new ReachedMap(*graph /*, false*/))),
170 own_reached_map(true) { }
171 ~DfsIterator() { if (own_reached_map) delete &reached; }
172 void pushAndSetReached(Node s) {
174 reached.set(s, true);
179 DfsIterator<Graph, /*OutEdgeIt,*/ ReachedMap>&
181 actual_edge=dfs_stack.top();
182 //actual_node=G.aNode(actual_edge);
183 if (graph->valid(actual_edge)/*.valid()*/) {
184 Node w=graph->bNode(actual_edge);
190 reached.set(w, true);
191 b_node_newly_reached=true;
193 actual_node=graph->aNode(actual_edge);
194 graph->next(dfs_stack.top());
195 b_node_newly_reached=false;
198 //actual_node=G.aNode(dfs_stack.top());
203 bool finished() const { return dfs_stack.empty(); }
204 operator OutEdgeIt() const { return actual_edge; }
205 bool isBNodeNewlyReached() const { return b_node_newly_reached; }
206 bool isANodeExamined() const { return !(graph->valid(actual_edge)); }
207 Node aNode() const { return actual_node; /*FIXME*/}
208 Node bNode() const { return graph->bNode(actual_edge); }
209 const ReachedMap& getReachedMap() const { return reached; }
210 const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; }
213 /// Dfs searches from s for the nodes wich are not marked in
215 /// Reached is a read-write bool-map, Pred is a write-nodemap, have to be.
216 template <typename Graph,
217 typename ReachedMap=typename Graph::template NodeMap<bool>,
219 =typename Graph::template NodeMap<typename Graph::Edge> >
220 class Dfs : public DfsIterator<Graph, ReachedMap> {
221 typedef DfsIterator<Graph, ReachedMap> Parent;
223 typedef typename Parent::Node Node;
226 Dfs<Graph, ReachedMap, PredMap>(const Graph& _graph, ReachedMap& _reached, PredMap& _pred) : DfsIterator<Graph, ReachedMap>(_graph, _reached), pred(&_pred) { }
227 /// s is marked to be reached and pushed in the bfs queue.
228 /// If the queue is empty, then the first out-edge is processed.
229 /// If s was not marked previously, then
230 /// in addition its pred is set to be INVALID.
231 /// if s was marked previuosly, then it is simply pushed.
233 if (this->reached[s]) {
234 Parent::pushAndSetReached(s);
236 Parent::pushAndSetReached(s);
237 pred.set(s, INVALID);
240 /// A bfs is processed from s.
243 while (!this->finished()) this->operator++();
245 Dfs<Graph, ReachedMap, PredMap> operator++() {
246 Parent::operator++();
247 if (this->graph->valid(this->actual_edge) && this->b_node_newly_reached)
249 pred.set(this->bNode(), this->actual_edge);
253 const PredMap& getPredMap() const { return pred; }
259 #endif //HUGO_BFS_ITERATOR_H