![]() |
|
|||
File indexing completed on 2025-08-03 08:19:36
0001 /* This software is distributed under the GNU Lesser General Public License */ 0002 //========================================================================== 0003 // 0004 // bfs.h 0005 // 0006 //========================================================================== 0007 // $Id: bfs.h,v 1.14 2003/03/24 15:58:54 raitner Exp $ 0008 0009 #ifndef GTL_BFS_H 0010 #define GTL_BFS_H 0011 0012 #include <GTL/GTL.h> 0013 #include <GTL/algorithm.h> 0014 #include <GTL/node_map.h> 0015 0016 #include <deque> 0017 0018 __GTL_BEGIN_NAMESPACE 0019 0020 /** 0021 * $Date: 2003/03/24 15:58:54 $ 0022 * $Revision: 1.14 $ 0023 * 0024 * @brief Breadth-First-Search (BFS) %algorithm. 0025 * 0026 * Encapsulates the BFS %algorithm together with all data 0027 * produced by it. There are a few parameters, which on the one 0028 * hand influence the behaviour of BFS (e.g. bfs::start_node) and 0029 * on the other hand toggle the storing of extra information, 0030 * such as the level-number of each %node. In detail these are: 0031 * - bfs::start_node 0032 * (default: an arbitrary %node will be chosen) 0033 * - bfs::scan_whole_graph states whether BFS will be 0034 * continued in the unused part of the %graph, if not all 0035 * nodes were touched at the end of BFS started at the start-%node. 0036 * (default: disabled) 0037 * - bfs::calc_level toggle storing of level-numbers for each 0038 * %node, i.e. its distance from the start-%node. 0039 * (default: disabled) 0040 * - bfs::store_preds toggle storing the predecessor of each 0041 * %node, i.e. the father in the BFS-tree. (default: disabled) 0042 * - bfs::store_non_tree_edges toggle storing of all non_tree_edges 0043 * (tree_edges are always stored) in a list and thus enable or disable 0044 * iteration through all non_tree_edges. 0045 * (default: disabled) 0046 * 0047 * @em Please @em note that the %algorithm always starts with the 0048 * given start-%node (if none was given, the first %node is chosen 0049 * and stored, thus after BFS the root of the tree is always 0050 * accesible via bfs::start_node) and continues until no more 0051 * unused nodes are reachable from already used ones. Thus if the 0052 * %graph isn't connected not @em all nodes will be reached. If 0053 * bfs::scan_whole_graph isn't set the BFS stops here. If it is 0054 * set, the BFS will be continued with the next unused %node and 0055 * so on until all nodes were used. 0056 * 0057 * For further customization a few virtual functions, so called 0058 * handler, are called at crucial stages of the %algorithm. In 0059 * this basic implementation all of these handler are empty. So 0060 * if one wants to add only a few lines of code (e.g. some new 0061 * numbering) he is likely to take this class as base-class and 0062 * override the handler where neccessary. In detail these are 0063 * (please look at the source code to see where they are called): 0064 * - bfs::init_handler 0065 * - bfs::end_handler 0066 * - bfs::popped_node_handler 0067 * - bfs::finished_node_handler 0068 * - bfs::unused_node_handler 0069 * - bfs::used_node_handler 0070 * - bfs::new_start_handler 0071 * 0072 * @em Please @em note: We do @em not claim that the set of 0073 * handlers provided is sufficient in any way. So if you believe 0074 * that some new handler is needed urgently please let us know. 0075 * 0076 * There is a lot of information stored during BFS (e.g. nodes in 0077 * bfs-order, list of non-tree edges). Some of it can be obtained directly 0078 * by using the corresponding member-function (e.g. bfs::bfs_num), 0079 * but all information that can be thought of as a list (e.g. nodes in 0080 * bfs-order) can be accessed through iterators. In detail these are (of 0081 * course depending on what options are chosen!): 0082 * - bfs::bfs_iterator 0083 * - bfs::tree_edges_iterator 0084 * - bfs::non_tree_edges_iterator 0085 * - bfs::roots_iterator 0086 */ 0087 class GTL_EXTERN bfs : public algorithm 0088 { 0089 public: 0090 0091 /** 0092 * @brief Constructor. 0093 */ 0094 bfs (); 0095 0096 /** 0097 * @brief Destructor. 0098 */ 0099 virtual ~bfs (); 0100 0101 int run (graph& G); 0102 0103 /** 0104 * @brief Checks whether the preconditions for BFS are satisfied. 0105 * 0106 * Currently there aren't any restricitions for the BFS %algorithm. 0107 * 0108 * @param G graph. 0109 * @retval algorithm::GTL_OK if %algorithm can be applied 0110 * @retval algorithm::GTL_ERROR otherwise. 0111 */ 0112 virtual int check (graph& G) { return GTL_OK; } 0113 0114 virtual void reset (); 0115 0116 //----------------------------------------------------------------------- 0117 // Parameters 0118 //----------------------------------------------------------------------- 0119 0120 /** 0121 * @brief Sets start-%node for BFS. 0122 * 0123 * The default start-%node is the invalid %node (node::node()), 0124 * in this case an arbitrary %node is chosen and stored when 0125 * BFS is run. 0126 * 0127 * @param n start-%node. 0128 */ 0129 void start_node (const node& n) {start = n;} 0130 0131 /** 0132 * @brief Returns start-%node for BFS. 0133 * 0134 * @return start-%node. 0135 */ 0136 node start_node () const {return start;} 0137 0138 /** 0139 * @brief Enables or disables scanning of the whole %graph. 0140 * 0141 * If enabled and the BFS started at the given start-%node 0142 * stops without having touched all nodes, it will be 0143 * continued with the next unused %node, and so on until all 0144 * nodes were used. This makes sure that for every %node 0145 * bfs::bfs_num is defined. 0146 * 0147 * If this feature is disabled, you are able to check what 0148 * nodes can be reached, when starting a BFS at the 0149 * start-%node, because for those not reached bfs::bfs_num 0150 * will be 0. 0151 * 0152 * @param set if true enable scanning the whole %graph. 0153 * @sa bfs::roots_begin, bfs::roots_end 0154 */ 0155 void scan_whole_graph (bool set) {whole_graph = set;} 0156 0157 /** 0158 * @brief Returns whether the whole graph will be scanned. 0159 * 0160 * @retval true iff the whole graph will be scanned. 0161 * @sa bfs::roots_begin, bfs::roots_end 0162 */ 0163 bool scan_whole_graph () const {return whole_graph;} 0164 0165 /** 0166 * @brief Enables or disables the calculation of level-numbers for each 0167 * %node. 0168 * 0169 * If enabled each %node gets a level-number, i.e. its 0170 * distance from the start-%node. 0171 * 0172 * @param set if true level-number will be calculated. 0173 * @sa bfs::level 0174 */ 0175 void calc_level (bool set); 0176 0177 /** 0178 * @brief Returns whether level-numbers will be calculated. 0179 * 0180 * @retval true iff level-numbers will be calculated. 0181 * @sa bfs::level 0182 */ 0183 bool calc_level () const {return level_number != 0;} 0184 0185 /** 0186 * @brief Enables or disables the storing of non-tree-edges. 0187 * 0188 * If enabled all non-tree-edges will be stored in 0189 * the order they occured. 0190 * 0191 * @param set if true non-tree-edges will be stored. 0192 * @sa bfs::non_tree_edges_begin, bfs::non_tree_edges_end 0193 */ 0194 void store_non_tree_edges (bool set); 0195 0196 /** 0197 * @brief Returns whether the storing of non-tree-edges is 0198 * enabled. 0199 * 0200 * @retval true iff the storing of non-tree-edges is enabled. 0201 * @sa bfs::non_tree_edges_begin, bfs::non_tree_edges_end 0202 */ 0203 bool store_non_tree_edges () const {return non_tree != 0;} 0204 0205 0206 /** 0207 * @brief Enables or disables the storing of predecessors. 0208 * 0209 * If enabled for every %node the predecessor in the BFS-forest 0210 * will be stored. 0211 * 0212 * @param set if true predecessors will be stored. 0213 * @sa bfs::father 0214 */ 0215 void store_preds (bool set); 0216 0217 /** 0218 * @brief Returns whether the storing of predecessors is enabled. 0219 * 0220 * @retval true iff the storing of predecessors is enabled. 0221 * @sa bfs::father 0222 */ 0223 bool store_preds () const {return preds != 0;} 0224 0225 /** 0226 * @brief Checks whether %node @a n was reached in BFS. 0227 * 0228 * @param n %node. 0229 * @retval true iff @a n was reached. 0230 */ 0231 bool reached (const node& n) const 0232 {return bfs_number[n] != 0;} 0233 0234 /** 0235 * @brief BFS-number of @a n. 0236 * 0237 * @em Please @em note that BFS-number 0 means that this %node wasn't 0238 * reached. 0239 * 0240 * @param n %node. 0241 * @return BFS-number of @a n. 0242 */ 0243 int bfs_num (const node& n) const 0244 {return bfs_number[n];} 0245 0246 /** 0247 * @brief BFS-number of @a n. 0248 * 0249 * @em Please @em note that BFS-number 0 means that this %node wasn't 0250 * reached. 0251 * 0252 * @param n %node. 0253 * @return BFS-number of @a n. 0254 */ 0255 int operator[] (const node& n) const 0256 {return bfs_number[n];} 0257 0258 /** 0259 * @brief Level-number of %node @a n. 0260 * 0261 * @em Please @em note that this requires that this option 0262 * was enabled during last run. 0263 * 0264 * @param n node. 0265 * @return level-number of @a n. 0266 * @sa bfs::calc_level 0267 */ 0268 int level (const node& n) const 0269 {assert (level_number); return (*level_number)[n];} 0270 0271 /** 0272 * @brief Father of %node @a n in BFS-forest. 0273 * 0274 * If @a n is a root in the forest or wasn't reached the 0275 * return value is the invalid %node node::node(). 0276 * 0277 * @em Please @em note that this requires that this option 0278 * was enabled during last run. 0279 * 0280 * @param n node. 0281 * @return Father of @a n. 0282 * @sa bfs::store_preds 0283 */ 0284 node father (const node& n) const 0285 {assert (preds); return (*preds)[n];} 0286 0287 /** 0288 * @brief Iterator for tree-edges. 0289 */ 0290 typedef list<edge>::const_iterator tree_edges_iterator; 0291 0292 /** 0293 * @brief Iterate through all tree-edges of last BFS. 0294 * 0295 * @em Please @em note that this edges not always form a 0296 * tree. In case the %graph is not (strongly) connected and 0297 * the whole graph was scanned, they form a forest. 0298 * 0299 * @return Start for iteration through all tree-edges. 0300 */ 0301 tree_edges_iterator tree_edges_begin () const 0302 {return tree.begin();} 0303 0304 /** 0305 * @brief End-iterator for iteration through all tree-edges 0306 * picked of last BFS. 0307 * 0308 * @return End for iteration through all tree-edges. 0309 */ 0310 tree_edges_iterator tree_edges_end () const 0311 {return tree.end();} 0312 0313 /** 0314 * @brief Iterator for nodes in BFS-order. 0315 */ 0316 typedef list<node>::const_iterator bfs_iterator; 0317 0318 /** 0319 * @brief Iterate through all (reached) nodes in BFS-Order. 0320 * 0321 * @return Start for iteration through all nodes in BFS-order. 0322 */ 0323 bfs_iterator begin () const 0324 {return bfs_order.begin();} 0325 0326 /** 0327 * @brief End-iterator for iteration through all (reached) 0328 * nodes in BFS-Order. 0329 * 0330 * @return End for iteration through all (reached) nodes 0331 */ 0332 bfs_iterator end () const 0333 {return bfs_order.end();} 0334 0335 /** 0336 * @brief Iterator for non-tree-edges. 0337 */ 0338 typedef list<edge>::const_iterator non_tree_edges_iterator; 0339 0340 /** 0341 * @brief Iterate through all non-tree-edges (if enabled). 0342 * 0343 * @return Start for iteration through all non-tree-edges. 0344 * @sa bfs::store_non_tree_edges 0345 */ 0346 non_tree_edges_iterator non_tree_edges_begin () const 0347 {assert (non_tree); return non_tree->begin(); } 0348 0349 /** 0350 * @brief End-iterator for iteration through all 0351 * non-tree-edges (if enabled). 0352 * 0353 * @return End for iteration through all non-tree-edges. 0354 * @sa bfs::store_non_tree_edges 0355 */ 0356 non_tree_edges_iterator non_tree_edges_end () const 0357 {assert (non_tree); return non_tree->end(); } 0358 0359 /** 0360 * @brief Iterator for roots of trees in BFS-forest. 0361 */ 0362 typedef list<bfs_iterator>::const_iterator roots_iterator; 0363 0364 /** 0365 * @brief Iterator pointing towards the first root in the 0366 * BFS-forest. 0367 * 0368 * @em Please @em note that instead of pointing directly 0369 * towards the %node (i.e. @c *it is of type @c node) 0370 * the iterator points towards a bfs-iterator, which 0371 * represents the root (i.e. @c *it is of type 0372 * @c bfs_iterator). 0373 * 0374 * Using this technique makes it possible not only to obtain 0375 * all the roots in the forest, but also the whole trees 0376 * associated with each one. This can be achieved because a 0377 * @c root_iterator specifies the exact position of the root 0378 * in the BFS-ordering and by definition of BFS all the 0379 * descendents of the root, i.e. the whole tree below, will 0380 * come later in BFS, such that by incrementing the @c 0381 * bfs_iterator a @c roots_iterator refers to, one can 0382 * traverse the whole tree with this given root. 0383 * 0384 * Of course if the root isn't the last %node in the 0385 * BFS-forest all following trees also will be traversed. But 0386 * since the first %node of such a tree, that will be 0387 * discovered, is its root, the successor of the @c 0388 * roots_iterator can be used as end-iterator. 0389 * 0390 * @return Start for iteration through all roots in BFS-forest. 0391 * @sa bfs::scan_whole_graph 0392 */ 0393 roots_iterator roots_begin () const 0394 {return roots.begin();} 0395 0396 /** 0397 * @brief Iterator pointing to the end of all roots. 0398 * 0399 * @return End for iteration through all roots in BFS-forest. 0400 * @sa bfs::scan_whole_graph 0401 */ 0402 roots_iterator roots_end () const 0403 {return roots.end();} 0404 0405 /** 0406 * @brief Number of nodes reached in last BFS. 0407 * 0408 * @return Number of reached nodes. 0409 * @sa bfs::scan_whole_graph 0410 */ 0411 int number_of_reached_nodes () const 0412 {return reached_nodes;} 0413 0414 //----------------------------------------------------------------------- 0415 // Handler 0416 //----------------------------------------------------------------------- 0417 0418 /** 0419 * @brief Called at the start of BFS. 0420 * 0421 * @param G %graph for which BFS was invoked. 0422 */ 0423 virtual void init_handler (graph& G) { }; 0424 0425 /** 0426 * @brief Called right before the end of BFS. 0427 * 0428 * @param G %graph for which BFS was invoked. 0429 */ 0430 virtual void end_handler (graph& G) { }; 0431 0432 /** 0433 * @brief Called after the %node @a n was taken out of the queue. 0434 * 0435 * @param G %graph for which BFS was invoked. 0436 * @param n %node taken out of the queue. 0437 */ 0438 virtual void popped_node_handler (graph& G, node& n) { }; 0439 0440 /** 0441 * @brief Called when finished with the %node @a n. 0442 0443 * A %node is finished after all its neighbors have been 0444 * visited. 0445 * 0446 * @param G %graph for which BFS was invoked. 0447 * @param n finished %node. 0448 */ 0449 virtual void finished_node_handler (graph& G, node& n) { }; 0450 0451 /** 0452 * @brief Called when an unused %node @a n was discovered. 0453 * 0454 * This means that the actual %node's @a f neighbor @a n was 0455 * not previously discovered. 0456 * 0457 * @param G %graph for which BFS was invoked. 0458 * @param n unused %node. 0459 * @param f actual %node. 0460 */ 0461 virtual void unused_node_handler (graph& G, node& n, node& f) { }; 0462 0463 /** 0464 * @brief Called when an used %node @a n was found. 0465 * 0466 * This means that the actual %node's (@a f) neighbor @a n 0467 * has already been discovered. 0468 * 0469 * @param G %graph for which BFS was invoked. 0470 * @param n used %node. 0471 * @param f actual %node. 0472 */ 0473 virtual void used_node_handler (graph& G, node& n, node& f) { }; 0474 0475 /** 0476 * @brief Called when BFS is started with start-%node 0477 * @a n. 0478 0479 * This is particularly useful when BFS was invoked with the 0480 * @c scan_whole_graph option. 0481 * 0482 * @param G %graph for which BFS was invoked. 0483 * @param n start-%node. 0484 * @sa bfs::scan_whole_graph 0485 */ 0486 virtual void new_start_handler (graph& G, node& n) { }; 0487 0488 private: 0489 0490 void bfs_sub (graph&, const node&, edge_map<int>*); 0491 0492 protected: 0493 0494 //----------------------------------------------------------------------- 0495 // Data 0496 //----------------------------------------------------------------------- 0497 0498 /** 0499 * @brief BFS number that will be assigned next. 0500 */ 0501 int act_bfs_num; 0502 0503 /** 0504 * @brief queue used in BFS. 0505 */ 0506 deque<node> qu; 0507 0508 /** 0509 * @brief List of nodes in BFS-order 0510 * 0511 * @sa bfs::begin, bfs::end 0512 */ 0513 list<node> bfs_order; 0514 0515 /** 0516 * @brief List of all edges of the BFS-tree 0517 * 0518 * @sa bfs::tree_edges_begin, bfs::tree_edges_end 0519 */ 0520 list<edge> tree; 0521 0522 /** 0523 * @brief Stores BFS-number of nodes. 0524 */ 0525 node_map<int> bfs_number; 0526 0527 /** 0528 * @brief Number of nodes reached so far. 0529 */ 0530 int reached_nodes; 0531 0532 /** 0533 * @brief List of all roots of the BFS-tree 0534 * 0535 * @sa bfs::roots_begin, bfs::roots_end 0536 */ 0537 list<bfs_iterator> roots; 0538 0539 //----------------------------------------------------------------------- 0540 // Optional 0541 //----------------------------------------------------------------------- 0542 0543 /** 0544 * @brief Stores whether whole %graph will be scanned. 0545 * 0546 * @sa bfs::scan_whole_graph 0547 */ 0548 bool whole_graph; 0549 0550 /** 0551 * @brief Stores start %node. 0552 * 0553 * @sa bfs:start_node 0554 */ 0555 node start; 0556 0557 /** 0558 * @brief Stores level number of each %node (if enabled) 0559 * 0560 * @sa bfs::calc_level 0561 */ 0562 node_map<int>* level_number; 0563 0564 /** 0565 * @brief List of non-tree edges (if enabled) 0566 * 0567 * @sa bfs::store_non_tree_edges 0568 */ 0569 list<edge>* non_tree; 0570 0571 /** 0572 * @brief Stores father of each %node (if enabled) 0573 * 0574 * @sa bfs::store_preds 0575 */ 0576 node_map<node>* preds; 0577 }; 0578 0579 __GTL_END_NAMESPACE 0580 0581 #endif // GTL_BFS_H 0582 0583 //-------------------------------------------------------------------------- 0584 // end of file 0585 //--------------------------------------------------------------------------
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |