Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:19:37

0001 /* This software is distributed under the GNU Lesser General Public License */
0002 //==========================================================================
0003 //
0004 //   st_number.h
0005 //
0006 //==========================================================================
0007 // $Id: st_number.h,v 1.17 2002/12/20 08:26:08 chris Exp $
0008 
0009 #ifndef GTL_ST_NUMBER_H
0010 #define GTL_ST_NUMBER_H
0011 
0012 #include <GTL/GTL.h>
0013 #include <GTL/graph.h>
0014 #include <GTL/node_map.h>
0015 #include <GTL/edge_map.h>
0016 #include <GTL/algorithm.h>
0017 
0018 #include <list>
0019 #include <utility>
0020 
0021 __GTL_BEGIN_NAMESPACE
0022 
0023 /**
0024 * @internal
0025 */
0026 class GTL_EXTERN pathfinder 
0027 {
0028 public:
0029     //---------------------------------------------------------- CONSTRUCTOR
0030     
0031     /**
0032      * @internal
0033      */
0034     pathfinder(const graph& G, edge st, node s);    
0035     
0036     /**
0037      * @internal
0038      */
0039     bool is_valid()
0040     {
0041     return is_biconn;
0042     }
0043     
0044     //------------------------------------------------------------- ITERATOR
0045     
0046     /**
0047      * @internal
0048      */
0049     class const_iterator 
0050     {
0051     public:
0052         /**
0053      * @internal
0054      */
0055     const_iterator(pathfinder& _pf) : pf (_pf)
0056     {
0057     }
0058 
0059         /**
0060      * @internal
0061      */
0062     const_iterator(pathfinder& _pf, node n);    
0063         
0064         /**
0065      * @internal
0066      */
0067     const_iterator& operator++();
0068         /**
0069      * @internal
0070      */
0071     const_iterator operator++(int);
0072         /**
0073      * @internal
0074      */
0075     const node& operator*() const 
0076     {
0077         return curr;
0078     }
0079         
0080         /**
0081      * @internal
0082      */
0083     bool operator==(const const_iterator& it) 
0084     {
0085         return curr == it.curr;
0086     }
0087 
0088         /**
0089      * @internal
0090      */
0091     bool operator!=(const const_iterator& it)
0092     {
0093         return curr != it.curr;
0094     }
0095     private:
0096         /**
0097      * @internal
0098      */
0099     enum iteration_state {END, UP, DOWN};
0100 
0101         /**
0102      * @internal
0103      */
0104     iteration_state state;
0105 
0106         /**
0107      * @internal
0108      */
0109     node curr;
0110 
0111         /**
0112      * @internal
0113      */
0114     pathfinder& pf;
0115     };
0116     
0117     /**
0118      * @internal
0119      */
0120     const_iterator path(node n)
0121     {
0122     return const_iterator(*this, n);
0123     }
0124     
0125     /**
0126      * @internal
0127      */
0128     const_iterator end()
0129     {
0130     return const_iterator (*this);
0131     }
0132     
0133 private:
0134     //------------------------------------------------------------ FUNCTIONS
0135         
0136     /**
0137      * @internal
0138      */
0139     void dfs_sub (node&, node&);
0140         
0141     //-------------------------------------------------------------- MEMBERS 
0142         
0143     /**
0144      * @internal
0145      */
0146     node_map<int> dfs_num;
0147 
0148     /**
0149      * @internal
0150      */
0151     node_map<int> low_num;
0152 
0153     /**
0154      * @internal
0155      */
0156     node_map<list<edge> > tree;
0157 
0158     /**
0159      * @internal
0160      */
0161     node_map<list<edge> > back;
0162 
0163     /**
0164      * @internal
0165      */
0166     node_map<list<edge> > forward;
0167 
0168     /**
0169      * @internal
0170      */
0171     node_map<list<edge>::iterator> to_low;
0172 
0173     /**
0174      * @internal
0175      */
0176     node_map<list<edge>::iterator> to_father;
0177         
0178     /**
0179      * @internal
0180      */
0181     typedef pair<list<edge>::iterator, list<edge>::iterator> pos_pair;
0182 
0183     /**
0184      * @internal
0185      */
0186     edge_map<pos_pair > pos;
0187 
0188     /**
0189      * @internal
0190      */
0191     node_map<int> used;
0192         
0193     /**
0194      * @internal
0195      */
0196     int act_dfs_num;
0197 
0198     /**
0199      * @internal
0200      */
0201     int new_nodes;
0202 
0203     /**
0204      * @internal
0205      */
0206     bool is_biconn;
0207         
0208     /**
0209      * @internal
0210      * Allows const_iterator private access.
0211      */
0212     friend class const_iterator;
0213 };
0214 
0215 /**
0216  * @brief ST-number algorithm.
0217  *
0218  * Encapsulates the st-number algorithm together with all the data produced
0219  * by it. 
0220  * <p>
0221  * Assigns an integer <tt>st[n]</tt> to each node @c n of a undirected,
0222  * biconnected graph, such that each node is connected with at least one
0223  * node having a smaller and with at least one having a larger number than
0224  * itself. The only exception to this rule are the endpoints of edge @a st
0225  * connecting nodes @a s (st-number 1) and @c t (highest st-number).
0226  * <p>
0227  * The following options are supported:
0228  * - #st_edge sets/retrieves the edge that connects the node with the lowest
0229  *   number to that with the highest.
0230  * - #s_node sets/retrieves that endpoints of the @a st_edge, which gets
0231  *   number 1.
0232  */
0233 class GTL_EXTERN st_number : public algorithm 
0234 {
0235 public:
0236     /**
0237      * @brief Default constructor.
0238      * Creates st-number object. Please note that there are no reasonable 
0239      * default settings for the parameters, i.e. the edge @s st connecting
0240      * the lowest with highest numbers node and which of its endpoints
0241      * should get number 1 (= node @a s) has to be specified always.
0242      */
0243     st_number() : algorithm()
0244     {
0245     }
0246 
0247     /**
0248      * @brief Destructor
0249      */
0250     virtual ~st_number()
0251     {
0252     }
0253     
0254     /**
0255      * @brief Sets edge @a st for the next run. 
0256      *
0257      * @param e edge @a st
0258      */
0259     void st_edge(edge e)
0260     {
0261     st = e;
0262     }
0263 
0264     /**
0265      * @brief Get edge @a st.
0266      *
0267      * @retval edge @a st
0268      */
0269     edge st_edge() const
0270     {
0271     return st;
0272     }
0273 
0274     /**
0275      * @brief Sets node @a s for next run.
0276      *
0277      * This must be one of the endpoints of edge @a st. This node will get
0278      * st-number 1 and thus the other endpoint will get the highest
0279      * st-number.
0280      *
0281      * @param n node @a s
0282      */
0283     void s_node(node n) 
0284     {
0285     s = n;
0286     }
0287 
0288     /**
0289      * @brief Get node @a s.
0290      *
0291      * @retval node @a s
0292      */
0293     node s_node() const
0294     {
0295     return s;
0296     }
0297 
0298     /**
0299      * @brief Returns st-number of node @p n as determined in the last run.
0300      *
0301      * @param n node
0302      *
0303      * @return st-number of @p n
0304      */
0305     int& operator[](const node& n)
0306     {
0307     return st_num[n];
0308     }
0309     
0310     /**
0311      * @internal
0312      */
0313     typedef list<node>::iterator iterator;
0314 
0315     /**
0316      * @internal
0317      */
0318     typedef list<node>::reverse_iterator reverse_iterator;
0319     
0320     /**
0321      * @brief Iteration through the nodes of graph st-numbered in last
0322      *        run in st-number order, i.e. from 1 to highest st-number.
0323      *
0324      * @return start of iteration through nodes in st-number order 
0325      */
0326     iterator begin()
0327     {
0328     return st_ord.begin();
0329     }   
0330 
0331     /**
0332      * @brief Iteration through nodes of graph in st-number order.
0333      *
0334      * @return end of iteration through nodes of graph in st-number order
0335      */
0336     iterator end()
0337     {
0338     return st_ord.end();
0339     }
0340     
0341     /**
0342      * @brief Iteration through the nodes of graph st-numbered in last run
0343      *        in reverse st-number order, i.e. from highest st-number down
0344      *        to 1.
0345      *
0346      * @return start of iteration through nodes in reverse st-number order 
0347      */
0348     reverse_iterator rbegin()
0349     {
0350     return st_ord.rbegin();
0351     }
0352     
0353     /**
0354      * @brief End of iteration through nodes of graph in reverse st-number
0355      *        order.
0356      *
0357      * @return end of iteration through nodes in reverse st-number order 
0358      */
0359     reverse_iterator rend()
0360     {
0361     return st_ord.rend();
0362     }
0363     
0364 
0365     /**
0366      * @brief Checks whether st-number algorithm can be applied to @p G.
0367      *
0368      * Besides from the trivial preconditions that edge @a st and node @a s
0369      * lie in @p G and @a s is really an endpoint of @a st (which isn't
0370      * checked), @p G must be undirected and biconnected.
0371      * @note As for all algorithms in GTL, #check must be called, because it
0372      * might do some initialization.
0373      *
0374      * @param G graph
0375      *
0376      * @retval algorithm::GTL_OK iff st-number algorithm may be applied
0377      *
0378      * @sa algorithm::check
0379      */
0380     int check(graph& G);
0381 
0382 
0383     /**
0384      * @brief Runs st-number algorithm on graph @p G.
0385      *
0386      * It is assumed that #check was called previously and returned
0387      * algorithm::GTL_OK.
0388      *
0389      * @param G graph
0390      *
0391      * @return algorithm::GTL_OK iff @p G could be correctly st-numbered
0392      *
0393      * @sa algorithm::run
0394      */
0395     int run(graph& G);
0396 
0397 
0398     /**
0399      * @brief Resets algorithm in order to be applied to the next graph.
0400      *
0401      * This will delete most of the information obtained in the last run.
0402      * 
0403      * @sa algorithm::reset
0404      */
0405     void reset()
0406     {
0407     st_ord.erase (st_ord.begin(), st_ord.end());
0408     }
0409 protected:
0410     /**
0411      * @internal
0412      */    
0413     edge st;
0414 
0415     /**
0416      * @internal
0417      */
0418     node s;
0419 
0420     /**
0421      * @internal
0422      */
0423     pathfinder* pf;
0424 
0425     /**
0426      * @internal
0427      */
0428     list<node> st_ord;
0429 
0430     /**
0431      * @internal
0432      */
0433     node_map<int> st_num;
0434 };
0435 
0436 __GTL_END_NAMESPACE
0437 
0438 #endif // GTL_ST_NUMBER_H
0439 
0440 //--------------------------------------------------------------------------
0441 //   end of file
0442 //--------------------------------------------------------------------------