2 #ifndef LEMON_BFS_DFS_H
3 #define LEMON_BFS_DFS_H
7 /// \brief Bfs and dfs iterators.
9 /// This file contains bfs and dfs iterator classes.
11 // /// \author Marton Makai
17 #include <lemon/invalid.h>
22 /// Bfs searches for the nodes wich are not marked in
24 /// RM have to be a read-write bool node-map.
26 template <typename Graph, /*typename OutEdgeIt,*/
27 typename RM/*=typename Graph::NodeMap<bool>*/ >
30 typedef RM ReachedMap;
32 typedef typename Graph::Node Node;
33 typedef typename Graph::Edge Edge;
34 typedef typename Graph::OutEdgeIt OutEdgeIt;
36 std::queue<Node> bfs_queue;
37 ReachedMap* reached_map;
38 bool b_node_newly_reached;
39 //OutEdgeIt actual_edge;
42 BfsIterator(const Graph& _graph) : graph(&_graph), reached_map(0) { }
43 /// RM have to be set before any bfs operation.
44 BfsIterator<Graph, RM>& setReached(RM& _reached_map) {
45 reached_map=&_reached_map;
48 /// In that constructor \c _reached_map have to be a reference
49 /// for a bool bode-map. The algorithm will search for the
50 /// initially \c false nodes
52 BfsIterator(const Graph& _graph, ReachedMap& _reached_map) :
53 graph(&_graph), reached_map(&_reached_map) { }
54 /// The same as above, but the map storing the reached nodes
55 /// is constructed dynamically to everywhere false.
57 // BfsIterator(const Graph& _graph) :
58 // graph(&_graph), reached_map(new ReachedMap(*graph /*, false*/)),
59 // own_reached_map(true) { }
60 // /// The map storing the reached nodes have to be destroyed if
61 // /// it was constructed dynamically
62 // ~BfsIterator() { if (own_reached_map) delete reached_map; }
63 /// This method markes \c s reached.
64 /// If the queue is empty, then \c s is pushed in the bfs queue
65 /// and the first out-edge is processed.
66 /// If the queue is not empty, then \c s is simply pushed.
67 BfsIterator<Graph, /*OutEdgeIt,*/ ReachedMap>& pushAndSetReached(Node s) {
68 reached_map->set(s, true);
69 if (bfs_queue.empty()) {
71 actual_edge=OutEdgeIt(*graph, s);
72 //graph->first(actual_edge, s);
73 if (actual_edge!=INVALID) {
74 Node w=graph->target(actual_edge);
75 if (!(*reached_map)[w]) {
77 reached_map->set(w, true);
78 b_node_newly_reached=true;
80 b_node_newly_reached=false;
88 /// As \c BfsIterator<Graph, ReachedMap> works as an edge-iterator,
89 /// its \c operator++() iterates on the edges in a bfs order.
90 BfsIterator<Graph, /*OutEdgeIt,*/ ReachedMap>&
92 if (actual_edge!=INVALID) {
93 actual_edge=++OutEdgeIt(*graph, actual_edge);
95 if (actual_edge!=INVALID) {
96 Node w=graph->target(actual_edge);
97 if (!(*reached_map)[w]) {
99 reached_map->set(w, true);
100 b_node_newly_reached=true;
102 b_node_newly_reached=false;
107 if (!bfs_queue.empty()) {
108 actual_edge=OutEdgeIt(*graph, bfs_queue.front());
109 //graph->first(actual_edge, bfs_queue.front());
110 if (actual_edge!=INVALID) {
111 Node w=graph->target(actual_edge);
112 if (!(*reached_map)[w]) {
114 reached_map->set(w, true);
115 b_node_newly_reached=true;
117 b_node_newly_reached=false;
124 /// Returns true iff the algorithm is finished.
125 bool finished() const { return bfs_queue.empty(); }
126 /// The conversion operator makes for converting the bfs-iterator
127 /// to an \c out-edge-iterator.
128 ///\bug Edge have to be in LEMON 0.2
129 operator Edge() const { return actual_edge; }
130 /// Returns if b-node has been reached just now.
131 bool isBNodeNewlyReached() const { return b_node_newly_reached; }
132 /// Returns if a-node is examined.
133 bool isANodeExamined() const { return actual_edge==INVALID; }
134 /// Returns a-node of the actual edge, so does if the edge is invalid.
135 Node source() const { return bfs_queue.front(); }
136 /// \pre The actual edge have to be valid.
137 Node target() const { return graph->target(actual_edge); }
140 const ReachedMap& reachedMap() const { return *reached_map; }
143 typename ReachedMap::Value reached(const Node& n) const {
144 return (*reached_map)[n];
148 const std::queue<Node>& getBfsQueue() const { return bfs_queue; }
151 /// Bfs searches for the nodes wich are not marked in
153 /// RM have to work as a read-write bool Node-map,
154 /// PM is a write edge node-map and
155 /// PNM is a write node node-map and
156 /// DM is a read-write node-map of integral value, have to be.
158 template <typename Graph,
159 typename RM=typename Graph::template NodeMap<bool>,
161 =typename Graph::template NodeMap<typename Graph::Edge>,
163 =typename Graph::template NodeMap<typename Graph::Node>,
164 typename DM=typename Graph::template NodeMap<int> >
165 class Bfs : public BfsIterator<Graph, RM> {
166 typedef BfsIterator<Graph, RM> Parent;
168 typedef RM ReachedMap;
170 typedef PNM PredNodeMap;
173 typedef typename Parent::Node Node;
175 PredNodeMap* pred_node_map;
178 Bfs<Graph, RM, PM, PNM, DM>
179 (const Graph& _graph) : BfsIterator<Graph, RM>(_graph) { }
180 /// PM have to be set before any bfs operation.
181 Bfs<Graph, RM, PM, PNM, DM>&
182 setPredMap(PredMap& _pred_map) {
185 /// PredNodeMap have to be set before any bfs operation.
186 Bfs<Graph, RM, PM, PNM, DM>&
187 setPredNodeMap(PredNodeMap& _pred_node_map) {
188 pred_node_map=&_pred_node_map;
190 /// DistMap have to be set before any bfs operation.
191 Bfs<Graph, RM, PM, PNM, DM>&
192 setDistMap(DistMap& _dist_map) {
196 /// The algorithm will search in a bfs order for
197 /// the nodes which are \c false initially.
198 /// The constructor makes no initial changes on the maps.
199 Bfs<Graph, RM, PM, PNM, DM>
200 (const Graph& _graph, ReachedMap& _reached_map,
201 PredMap& _pred_map, PredNodeMap& _pred_node_map,
202 DistMap& _dist_map) : BfsIterator<Graph, RM>(_graph, _reached_map),
203 pred_map(&_pred_map), pred_node_map(&_pred_node_map),
204 dist_map(&_dist_map) { }
205 /// \c s is marked to be reached and pushed in the bfs queue.
206 /// If the queue is empty, then the first out-edge is processed.
207 /// If \c s was not marked previously, then
208 /// in addition its pred_map is set to be \c INVALID,
209 /// and dist_map to \c 0.
210 /// if \c s was marked previuosly, then it is simply pushed.
211 Bfs<Graph, RM, PM, PNM, DM>& push(Node s) {
212 if ((*(this->reached_map))[s]) {
213 Parent::pushAndSetReached(s);
215 Parent::pushAndSetReached(s);
216 pred_map->set(s, INVALID);
217 pred_node_map->set(s, INVALID);
222 /// A bfs is processed from \c s.
223 Bfs<Graph, RM, PM, PNM, DM>& run(Node s) {
225 while (!this->finished()) this->operator++();
228 /// Beside the bfs iteration, \c pred_map and \dist_map are saved in a
229 /// newly reached node.
230 Bfs<Graph, RM, PM, PNM, DM>& operator++() {
231 Parent::operator++();
232 if ((this->actual_edge)!=INVALID && this->b_node_newly_reached)
234 pred_map->set(this->target(), this->actual_edge);
235 pred_node_map->set(this->target(), this->source());
236 dist_map->set(this->target(), (*dist_map)[this->source()]);
242 const PredMap& predMap() const { return *pred_map; }
245 typename PredMap::Value pred(const Node& n) const {
246 return (*pred_map)[n];
250 const PredNodeMap& predNodeMap() const { return *pred_node_map; }
253 typename PredNodeMap::Value predNode(const Node& n) const {
254 return (*pred_node_map)[n];
258 const DistMap& distMap() const { return *dist_map; }
261 typename DistMap::Value dist(const Node& n) const {
262 return (*dist_map)[n];
266 // template <typename Graph,
267 // typename RM=typename Graph::template NodeMap<bool>,
269 // =typename Graph::template NodeMap<typename Graph::Edge>,
270 // typename PredNodeMap
271 // =typename Graph::template NodeMap<typename Graph::Node>,
272 // typename DistMap=typename Graph::template NodeMap<int> >
273 // class BfsWizard : public Bfs<Graph> {
275 // typedef Bfs<Graph, PM, PredNodeMap, DistMap> Parent;
277 // typedef typename Parent::Node Node;
278 // bool own_reached_map;
279 // bool own_pred_map;
280 // bool own_pred_node_map;
281 // bool own_dist_map;
283 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
285 // own_reached_map=true;
286 // reached=new ReachedMap(*graph, false);
288 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
289 // deleteReachedMap() {
290 // own_reached_map=false;
294 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
296 // own_pred_map=true;
297 // pred_map=new PM(*graph, INVALID);
299 // BfsWizard<Graph, ReachedMap, PM, PredNodeMap, DistMap>&
301 // own_pred_map=false;
305 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
306 // makePredNodeMap() {
307 // own_pred_node_map=true;
308 // pred_node_map=new PredNodeMap(*graph, INVALID);
310 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
311 // deletePredNodeMap() {
312 // own_pred_node_map=false;
313 // delete pred_node_map;
316 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
318 // own_dist_map=true;
319 // dist_map=new DistMap(*graph, 0);
321 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
323 // own_dist_map=false;
328 // /// User friendly Bfs class.
329 // /// The maps which are not explicitly given by the user are
330 // /// constructed with false, INVALID, INVALID and 0 values.
331 // /// For the user defined maps, the values are not modified, and
332 // /// the bfs is processed without any preset on maps. Therefore,
333 // /// the bfs will search only the nodes which are set false previously
334 // /// in reached, and in the nodes wich are not newly reached by the
335 // /// search, the map values are not modified.
336 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>
337 // (const Graph& _graph) :
338 // own_reached_map(false),
339 // own_pred_map(false),
340 // own_pred_node_map(false),
341 // own_dist_map(false) {
345 // ~BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>() {
346 // if (own_reached_map) deleteReachedMap();
347 // if (own_pred_map) deletePM();
348 // if (own_pred_node_map) deletePredNodeMap();
349 // if (own_dist_map) deleteDistMap();
353 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
354 // setReachedMap(ReachedMap& _reached) {
355 // if (own_reached_map) deleteReachedMap();
356 // Parent::setReachedMap(_reached);
359 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
360 // setPM(PM& _pred) {
361 // if (own_pred_map) deletePM();
362 // Parent::setPM(_pred);
365 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
366 // setPredNodeMap(PredNodeMap& _pred_node) {
367 // if (own_pred_node_map) deletePredNodeMap();
368 // Parent::setPredNodeMap(_pred_node);
371 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
372 // setDistMap(DistMap& _dist) {
373 // if (own_dist_map) deleteDistMap();
374 // Parent::setDistMap(_dist);
378 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
380 // if (!reached) makeReachedMap();
381 // if (!pred_map) makePMMap();
382 // if (!pred_node_map) makePredNodeMap();
383 // if (!dist_map) makeDistMap();
389 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
391 // if (!reached) makeRM();
392 // if (!pred_map) makePMMap();
393 // if (!pred_node_map) makePredNodeMap();
394 // if (!dist_map) makeDistMap();
400 // BfsWizard<Graph, RM, PM, PredNodeMap, DistMap>&
402 // if (!reached) makeRM();
403 // if (!pred_map) makePMMap();
404 // if (!pred_node_map) makePredNodeMap();
405 // if (!dist_map) makeDistMap();
413 /// Dfs searches for the nodes wich are not marked in
415 /// Reached have to be a read-write bool Node-map.
417 template <typename Graph, /*typename OutEdgeIt,*/
418 typename ReachedMap/*=typename Graph::NodeMap<bool>*/ >
421 typedef typename Graph::Node Node;
422 typedef typename Graph::Edge Edge;
423 typedef typename Graph::OutEdgeIt OutEdgeIt;
425 std::stack<OutEdgeIt> dfs_stack;
426 bool b_node_newly_reached;
430 bool own_reached_map;
432 /// In that constructor \c _reached have to be a reference
433 /// for a bool node-map. The algorithm will search in a dfs order for
434 /// the nodes which are \c false initially
435 DfsIterator(const Graph& _graph, ReachedMap& _reached) :
436 graph(&_graph), reached(_reached),
437 own_reached_map(false) { }
438 /// The same as above, but the map of reached nodes is
439 /// constructed dynamically
440 /// to everywhere false.
441 DfsIterator(const Graph& _graph) :
442 graph(&_graph), reached(*(new ReachedMap(*graph /*, false*/))),
443 own_reached_map(true) { }
444 ~DfsIterator() { if (own_reached_map) delete &reached; }
445 /// This method markes s reached and first out-edge is processed.
446 DfsIterator<Graph, /*OutEdgeIt,*/ ReachedMap>& pushAndSetReached(Node s) {
448 reached.set(s, true);
449 OutEdgeIt e(*graph, s);
450 //graph->first(e, s);
454 /// As \c DfsIterator<Graph, ReachedMap> works as an edge-iterator,
455 /// its \c operator++() iterates on the edges in a dfs order.
456 DfsIterator<Graph, /*OutEdgeIt,*/ ReachedMap>&
458 actual_edge=dfs_stack.top();
459 if (actual_edge!=INVALID/*.valid()*/) {
460 Node w=graph->target(actual_edge);
463 OutEdgeIt e(*graph, w);
464 //graph->first(e, w);
466 reached.set(w, true);
467 b_node_newly_reached=true;
469 actual_node=graph->source(actual_edge);
471 b_node_newly_reached=false;
474 //actual_node=G.aNode(dfs_stack.top());
479 /// Returns true iff the algorithm is finished.
480 bool finished() const { return dfs_stack.empty(); }
481 /// The conversion operator makes for converting the bfs-iterator
482 /// to an \c out-edge-iterator.
483 ///\bug Edge have to be in LEMON 0.2
484 operator Edge() const { return actual_edge; }
485 /// Returns if b-node has been reached just now.
486 bool isBNodeNewlyReached() const { return b_node_newly_reached; }
487 /// Returns if a-node is examined.
488 bool isANodeExamined() const { return actual_edge==INVALID; }
489 /// Returns a-node of the actual edge, so does if the edge is invalid.
490 Node source() const { return actual_node; /*FIXME*/}
491 /// Returns b-node of the actual edge.
492 /// \pre The actual edge have to be valid.
493 Node target() const { return graph->target(actual_edge); }
496 const ReachedMap& getReachedMap() const { return reached; }
499 const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; }
502 /// Dfs searches for the nodes wich are not marked in
504 /// Reached is a read-write bool node-map,
505 /// Pred is a write node-map, have to be.
507 template <typename Graph,
508 typename ReachedMap=typename Graph::template NodeMap<bool>,
510 =typename Graph::template NodeMap<typename Graph::Edge> >
511 class Dfs : public DfsIterator<Graph, ReachedMap> {
512 typedef DfsIterator<Graph, ReachedMap> Parent;
514 typedef typename Parent::Node Node;
517 /// The algorithm will search in a dfs order for
518 /// the nodes which are \c false initially.
519 /// The constructor makes no initial changes on the maps.
520 Dfs<Graph, ReachedMap, PredMap>(const Graph& _graph, ReachedMap& _reached, PredMap& _pred) : DfsIterator<Graph, ReachedMap>(_graph, _reached), pred(_pred) { }
521 /// \c s is marked to be reached and pushed in the bfs queue.
522 /// If the queue is empty, then the first out-edge is processed.
523 /// If \c s was not marked previously, then
524 /// in addition its pred is set to be \c INVALID.
525 /// if \c s was marked previuosly, then it is simply pushed.
526 Dfs<Graph, ReachedMap, PredMap>& push(Node s) {
527 if (this->reached[s]) {
528 Parent::pushAndSetReached(s);
530 Parent::pushAndSetReached(s);
531 pred.set(s, INVALID);
535 /// A bfs is processed from \c s.
536 Dfs<Graph, ReachedMap, PredMap>& run(Node s) {
538 while (!this->finished()) this->operator++();
541 /// Beside the dfs iteration, \c pred is saved in a
542 /// newly reached node.
543 Dfs<Graph, ReachedMap, PredMap>& operator++() {
544 Parent::operator++();
545 if (this->graph->valid(this->actual_edge) && this->b_node_newly_reached)
547 pred.set(this->target(), this->actual_edge);
553 const PredMap& getPredMap() const { return pred; }
559 #endif //LEMON_BFS_DFS_H