Back to home page

sPhenix code displayed by LXR

 
 

    


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 //--------------------------------------------------------------------------