21 ReachedMap& reached; |
24 ReachedMap& reached; |
22 bool b_node_newly_reached; |
25 bool b_node_newly_reached; |
23 OutEdgeIt actual_edge; |
26 OutEdgeIt actual_edge; |
24 bool own_reached_map; |
27 bool own_reached_map; |
25 public: |
28 public: |
|
29 /// In that constructor \c _reached have to be a reference |
|
30 /// for a bool Node-map. The algorithm will search in a bfs order for |
|
31 /// the nodes which are \c false initially |
26 BfsIterator(const Graph& _graph, ReachedMap& _reached) : |
32 BfsIterator(const Graph& _graph, ReachedMap& _reached) : |
27 graph(&_graph), reached(_reached), |
33 graph(&_graph), reached(_reached), |
28 own_reached_map(false) { } |
34 own_reached_map(false) { } |
|
35 /// The same as above, but the map storing the reached nodes |
|
36 /// is constructed dynamically to everywhere false. |
29 BfsIterator(const Graph& _graph) : |
37 BfsIterator(const Graph& _graph) : |
30 graph(&_graph), reached(*(new ReachedMap(*graph /*, false*/))), |
38 graph(&_graph), reached(*(new ReachedMap(*graph /*, false*/))), |
31 own_reached_map(true) { } |
39 own_reached_map(true) { } |
|
40 /// The storing the reached nodes have to be destroyed if |
|
41 /// it was constructed dynamically |
32 ~BfsIterator() { if (own_reached_map) delete &reached; } |
42 ~BfsIterator() { if (own_reached_map) delete &reached; } |
33 /// This method markes s reached. |
43 /// This method markes \c s reached. |
34 /// If the queue is empty, then s is pushed in the bfs queue |
44 /// If the queue is empty, then \c s is pushed in the bfs queue |
35 /// and the first OutEdgeIt is processed. |
45 /// and the first out-edge is processed. |
36 /// If the queue is not empty, then s is simply pushed. |
46 /// If the queue is not empty, then \c s is simply pushed. |
37 void pushAndSetReached(Node s) { |
47 void pushAndSetReached(Node s) { |
38 reached.set(s, true); |
48 reached.set(s, true); |
39 if (bfs_queue.empty()) { |
49 if (bfs_queue.empty()) { |
40 bfs_queue.push(s); |
50 bfs_queue.push(s); |
41 graph->first(actual_edge, s); |
51 graph->first(actual_edge, s); |
85 } |
95 } |
86 } |
96 } |
87 } |
97 } |
88 return *this; |
98 return *this; |
89 } |
99 } |
|
100 /// |
90 bool finished() const { return bfs_queue.empty(); } |
101 bool finished() const { return bfs_queue.empty(); } |
91 /// The conversion operator makes for converting the bfs-iterator |
102 /// The conversion operator makes for converting the bfs-iterator |
92 /// to an \c out-edge-iterator. |
103 /// to an \c out-edge-iterator. |
|
104 ///\bug Edge have to be in HUGO 0.2 |
93 operator OutEdgeIt() const { return actual_edge; } |
105 operator OutEdgeIt() const { return actual_edge; } |
|
106 /// |
94 bool isBNodeNewlyReached() const { return b_node_newly_reached; } |
107 bool isBNodeNewlyReached() const { return b_node_newly_reached; } |
|
108 /// |
95 bool isANodeExamined() const { return !(graph->valid(actual_edge)); } |
109 bool isANodeExamined() const { return !(graph->valid(actual_edge)); } |
|
110 /// |
96 Node aNode() const { return bfs_queue.front(); } |
111 Node aNode() const { return bfs_queue.front(); } |
|
112 /// |
97 Node bNode() const { return graph->bNode(actual_edge); } |
113 Node bNode() const { return graph->bNode(actual_edge); } |
|
114 /// |
98 const ReachedMap& getReachedMap() const { return reached; } |
115 const ReachedMap& getReachedMap() const { return reached; } |
|
116 /// |
99 const std::queue<Node>& getBfsQueue() const { return bfs_queue; } |
117 const std::queue<Node>& getBfsQueue() const { return bfs_queue; } |
100 }; |
118 }; |
101 |
119 |
102 /// Bfs searches from s for the nodes wich are not marked in |
120 /// Bfs searches for the nodes wich are not marked in |
103 /// \c reached_map |
121 /// \c reached_map |
104 /// Reached is a read-write bool-map, Pred is a write-nodemap |
122 /// Reached have to work as a read-write bool Node-map, |
105 /// and dist is an rw-nodemap, have to be. |
123 /// Pred is a write Edge Node-map and |
|
124 /// Dist is a read-write int Node-map, have to be. |
|
125 ///\todo In fact onsly simple operations requirement are needed for |
|
126 /// Dist::Value. |
106 template <typename Graph, |
127 template <typename Graph, |
107 typename ReachedMap=typename Graph::template NodeMap<bool>, |
128 typename ReachedMap=typename Graph::template NodeMap<bool>, |
108 typename PredMap |
129 typename PredMap |
109 =typename Graph::template NodeMap<typename Graph::Edge>, |
130 =typename Graph::template NodeMap<typename Graph::Edge>, |
110 typename DistMap=typename Graph::template NodeMap<int> > |
131 typename DistMap=typename Graph::template NodeMap<int> > |
113 protected: |
134 protected: |
114 typedef typename Parent::Node Node; |
135 typedef typename Parent::Node Node; |
115 PredMap& pred; |
136 PredMap& pred; |
116 DistMap& dist; |
137 DistMap& dist; |
117 public: |
138 public: |
|
139 /// The algorithm will search in a bfs order for |
|
140 /// the nodes which are \c false initially. |
|
141 /// The constructor makes no initial changes on the maps. |
118 Bfs<Graph, ReachedMap, PredMap, DistMap>(const Graph& _graph, ReachedMap& _reached, PredMap& _pred, DistMap& _dist) : BfsIterator<Graph, ReachedMap>(_graph, _reached), pred(&_pred), dist(&_dist) { } |
142 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. |
143 /// \c 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. |
144 /// If the queue is empty, then the first out-edge is processed. |
121 /// If s was not marked previously, then |
145 /// If \c s was not marked previously, then |
122 /// in addition its pred is set to be INVALID, and dist to 0. |
146 /// in addition its pred is set to be \c INVALID, and dist to \c 0. |
123 /// if s was marked previuosly, then it is simply pushed. |
147 /// if \c s was marked previuosly, then it is simply pushed. |
124 void push(Node s) { |
148 void push(Node s) { |
125 if (this->reached[s]) { |
149 if (this->reached[s]) { |
126 Parent::pushAndSetReached(s); |
150 Parent::pushAndSetReached(s); |
127 } else { |
151 } else { |
128 Parent::pushAndSetReached(s); |
152 Parent::pushAndSetReached(s); |
129 pred.set(s, INVALID); |
153 pred.set(s, INVALID); |
130 dist.set(s, 0); |
154 dist.set(s, 0); |
131 } |
155 } |
132 } |
156 } |
133 /// A bfs is processed from s. |
157 /// A bfs is processed from \c s. |
134 void run(Node s) { |
158 void run(Node s) { |
135 push(s); |
159 push(s); |
136 while (!this->finished()) this->operator++(); |
160 while (!this->finished()) this->operator++(); |
137 } |
161 } |
|
162 /// Beside the bfs iteration, \c pred and \dist are saved in a |
|
163 /// newly reached node. |
138 Bfs<Graph, ReachedMap, PredMap, DistMap> operator++() { |
164 Bfs<Graph, ReachedMap, PredMap, DistMap> operator++() { |
139 Parent::operator++(); |
165 Parent::operator++(); |
140 if (this->graph->valid(this->actual_edge) && this->b_node_newly_reached) |
166 if (this->graph->valid(this->actual_edge) && this->b_node_newly_reached) |
141 { |
167 { |
142 pred.set(this->bNode(), this->actual_edge); |
168 pred.set(this->bNode(), this->actual_edge); |
143 dist.set(this->bNode(), dist[this->aNode()]); |
169 dist.set(this->bNode(), dist[this->aNode()]); |
144 } |
170 } |
145 return *this; |
171 return *this; |
146 } |
172 } |
|
173 /// |
147 const PredMap& getPredMap() const { return pred; } |
174 const PredMap& getPredMap() const { return pred; } |
|
175 /// |
148 const DistMap& getDistMap() const { return dist; } |
176 const DistMap& getDistMap() const { return dist; } |
149 }; |
177 }; |
150 |
178 |
|
179 /// Dfs searches for the nodes wich are not marked in |
|
180 /// \c reached_map |
|
181 /// Reached have to be a read-write bool Node-map. |
151 template <typename Graph, /*typename OutEdgeIt,*/ |
182 template <typename Graph, /*typename OutEdgeIt,*/ |
152 typename ReachedMap/*=typename Graph::NodeMap<bool>*/ > |
183 typename ReachedMap/*=typename Graph::NodeMap<bool>*/ > |
153 class DfsIterator { |
184 class DfsIterator { |
154 protected: |
185 protected: |
155 typedef typename Graph::Node Node; |
186 typedef typename Graph::Node Node; |
160 OutEdgeIt actual_edge; |
191 OutEdgeIt actual_edge; |
161 Node actual_node; |
192 Node actual_node; |
162 ReachedMap& reached; |
193 ReachedMap& reached; |
163 bool own_reached_map; |
194 bool own_reached_map; |
164 public: |
195 public: |
|
196 /// In that constructor \c _reached have to be a reference |
|
197 /// for a bool Node-map. The algorithm will search in a dfs order for |
|
198 /// the nodes which are \c false initially |
165 DfsIterator(const Graph& _graph, ReachedMap& _reached) : |
199 DfsIterator(const Graph& _graph, ReachedMap& _reached) : |
166 graph(&_graph), reached(_reached), |
200 graph(&_graph), reached(_reached), |
167 own_reached_map(false) { } |
201 own_reached_map(false) { } |
|
202 /// The same as above, but the map of reached nodes is |
|
203 /// constructed dynamically |
|
204 /// to everywhere false. |
168 DfsIterator(const Graph& _graph) : |
205 DfsIterator(const Graph& _graph) : |
169 graph(&_graph), reached(*(new ReachedMap(*graph /*, false*/))), |
206 graph(&_graph), reached(*(new ReachedMap(*graph /*, false*/))), |
170 own_reached_map(true) { } |
207 own_reached_map(true) { } |
171 ~DfsIterator() { if (own_reached_map) delete &reached; } |
208 ~DfsIterator() { if (own_reached_map) delete &reached; } |
|
209 /// This method markes s reached and first out-edge is processed. |
172 void pushAndSetReached(Node s) { |
210 void pushAndSetReached(Node s) { |
173 actual_node=s; |
211 actual_node=s; |
174 reached.set(s, true); |
212 reached.set(s, true); |
175 OutEdgeIt e; |
213 OutEdgeIt e; |
176 graph->first(e, s); |
214 graph->first(e, s); |
177 dfs_stack.push(e); |
215 dfs_stack.push(e); |
178 } |
216 } |
|
217 /// As \c DfsIterator<Graph, ReachedMap> works as an edge-iterator, |
|
218 /// its \c operator++() iterates on the edges in a dfs order. |
179 DfsIterator<Graph, /*OutEdgeIt,*/ ReachedMap>& |
219 DfsIterator<Graph, /*OutEdgeIt,*/ ReachedMap>& |
180 operator++() { |
220 operator++() { |
181 actual_edge=dfs_stack.top(); |
221 actual_edge=dfs_stack.top(); |
182 //actual_node=G.aNode(actual_edge); |
222 //actual_node=G.aNode(actual_edge); |
183 if (graph->valid(actual_edge)/*.valid()*/) { |
223 if (graph->valid(actual_edge)/*.valid()*/) { |
198 //actual_node=G.aNode(dfs_stack.top()); |
238 //actual_node=G.aNode(dfs_stack.top()); |
199 dfs_stack.pop(); |
239 dfs_stack.pop(); |
200 } |
240 } |
201 return *this; |
241 return *this; |
202 } |
242 } |
|
243 /// |
203 bool finished() const { return dfs_stack.empty(); } |
244 bool finished() const { return dfs_stack.empty(); } |
|
245 /// |
204 operator OutEdgeIt() const { return actual_edge; } |
246 operator OutEdgeIt() const { return actual_edge; } |
|
247 /// |
205 bool isBNodeNewlyReached() const { return b_node_newly_reached; } |
248 bool isBNodeNewlyReached() const { return b_node_newly_reached; } |
|
249 /// |
206 bool isANodeExamined() const { return !(graph->valid(actual_edge)); } |
250 bool isANodeExamined() const { return !(graph->valid(actual_edge)); } |
|
251 /// |
207 Node aNode() const { return actual_node; /*FIXME*/} |
252 Node aNode() const { return actual_node; /*FIXME*/} |
|
253 /// |
208 Node bNode() const { return graph->bNode(actual_edge); } |
254 Node bNode() const { return graph->bNode(actual_edge); } |
|
255 /// |
209 const ReachedMap& getReachedMap() const { return reached; } |
256 const ReachedMap& getReachedMap() const { return reached; } |
|
257 /// |
210 const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; } |
258 const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; } |
211 }; |
259 }; |
212 |
260 |
213 /// Dfs searches from s for the nodes wich are not marked in |
261 /// Dfs searches for the nodes wich are not marked in |
214 /// \c reached_map |
262 /// \c reached_map |
215 /// Reached is a read-write bool-map, Pred is a write-nodemap, have to be. |
263 /// Reached is a read-write bool Node-map, |
|
264 /// Pred is a write Node-map, have to be. |
216 template <typename Graph, |
265 template <typename Graph, |
217 typename ReachedMap=typename Graph::template NodeMap<bool>, |
266 typename ReachedMap=typename Graph::template NodeMap<bool>, |
218 typename PredMap |
267 typename PredMap |
219 =typename Graph::template NodeMap<typename Graph::Edge> > |
268 =typename Graph::template NodeMap<typename Graph::Edge> > |
220 class Dfs : public DfsIterator<Graph, ReachedMap> { |
269 class Dfs : public DfsIterator<Graph, ReachedMap> { |
221 typedef DfsIterator<Graph, ReachedMap> Parent; |
270 typedef DfsIterator<Graph, ReachedMap> Parent; |
222 protected: |
271 protected: |
223 typedef typename Parent::Node Node; |
272 typedef typename Parent::Node Node; |
224 PredMap& pred; |
273 PredMap& pred; |
225 public: |
274 public: |
|
275 /// The algorithm will search in a dfs order for |
|
276 /// the nodes which are \c false initially. |
|
277 /// The constructor makes no initial changes on the maps. |
226 Dfs<Graph, ReachedMap, PredMap>(const Graph& _graph, ReachedMap& _reached, PredMap& _pred) : DfsIterator<Graph, ReachedMap>(_graph, _reached), pred(&_pred) { } |
278 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. |
279 /// \c 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. |
280 /// If the queue is empty, then the first out-edge is processed. |
229 /// If s was not marked previously, then |
281 /// If \c s was not marked previously, then |
230 /// in addition its pred is set to be INVALID. |
282 /// in addition its pred is set to be \c INVALID. |
231 /// if s was marked previuosly, then it is simply pushed. |
283 /// if \c s was marked previuosly, then it is simply pushed. |
232 void push(Node s) { |
284 void push(Node s) { |
233 if (this->reached[s]) { |
285 if (this->reached[s]) { |
234 Parent::pushAndSetReached(s); |
286 Parent::pushAndSetReached(s); |
235 } else { |
287 } else { |
236 Parent::pushAndSetReached(s); |
288 Parent::pushAndSetReached(s); |
237 pred.set(s, INVALID); |
289 pred.set(s, INVALID); |
238 } |
290 } |
239 } |
291 } |
240 /// A bfs is processed from s. |
292 /// A bfs is processed from \c s. |
241 void run(Node s) { |
293 void run(Node s) { |
242 push(s); |
294 push(s); |
243 while (!this->finished()) this->operator++(); |
295 while (!this->finished()) this->operator++(); |
244 } |
296 } |
|
297 /// Beside the dfs iteration, \c pred is saved in a |
|
298 /// newly reached node. |
245 Dfs<Graph, ReachedMap, PredMap> operator++() { |
299 Dfs<Graph, ReachedMap, PredMap> operator++() { |
246 Parent::operator++(); |
300 Parent::operator++(); |
247 if (this->graph->valid(this->actual_edge) && this->b_node_newly_reached) |
301 if (this->graph->valid(this->actual_edge) && this->b_node_newly_reached) |
248 { |
302 { |
249 pred.set(this->bNode(), this->actual_edge); |
303 pred.set(this->bNode(), this->actual_edge); |
250 } |
304 } |
251 return *this; |
305 return *this; |
252 } |
306 } |
|
307 /// |
253 const PredMap& getPredMap() const { return pred; } |
308 const PredMap& getPredMap() const { return pred; } |
254 }; |
309 }; |
255 |
310 |
256 |
311 |
257 } // namespace hugo |
312 } // namespace hugo |