epoc32/include/stdapis/boost/graph/cuthill_mckee_ordering.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
     1 //=======================================================================
     2 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
     3 // Copyright 2004, 2005 Trustees of Indiana University
     4 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
     5 //          Doug Gregor, D. Kevin McGrath
     6 //
     7 // Distributed under the Boost Software License, Version 1.0. (See
     8 // accompanying file LICENSE_1_0.txt or copy at
     9 // http://www.boost.org/LICENSE_1_0.txt)
    10 //=======================================================================
    11 #ifndef BOOST_GRAPH_CUTHILL_MCKEE_HPP
    12 #define BOOST_GRAPH_CUTHILL_MCKEE_HPP
    13 
    14 #include <boost/config.hpp>
    15 #include <boost/graph/detail/sparse_ordering.hpp>
    16 #include <algorithm>
    17 
    18 
    19 /*
    20   (Reverse) Cuthill-McKee Algorithm for matrix reordering
    21 */
    22 
    23 namespace boost {
    24 
    25   namespace detail {
    26 
    27 
    28 
    29     template < typename OutputIterator, typename Buffer, typename DegreeMap > 
    30     class bfs_rcm_visitor:public default_bfs_visitor
    31     {
    32     public:
    33       bfs_rcm_visitor(OutputIterator *iter, Buffer *b, DegreeMap deg): 
    34         permutation(iter), Qptr(b), degree(deg) { }
    35       template <class Vertex, class Graph>
    36       void examine_vertex(Vertex u, Graph&) {
    37         *(*permutation)++ = u;
    38         index_begin = Qptr->size();
    39       }
    40       template <class Vertex, class Graph>
    41       void finish_vertex(Vertex, Graph&) {
    42         using std::sort;
    43 
    44         typedef typename property_traits<DegreeMap>::value_type ds_type;
    45 
    46         typedef indirect_cmp<DegreeMap, std::less<ds_type> > Compare;
    47         Compare comp(degree);
    48                 
    49         sort(Qptr->begin()+index_begin, Qptr->end(), comp);
    50       }
    51     protected:
    52       OutputIterator *permutation;
    53       int index_begin;
    54       Buffer *Qptr;
    55       DegreeMap degree;
    56     };
    57 
    58   } // namespace detail  
    59 
    60 
    61   // Reverse Cuthill-McKee algorithm with a given starting Vertex.
    62   //
    63   // If user provides a reverse iterator, this will be a reverse-cuthill-mckee
    64   // algorithm, otherwise it will be a standard CM algorithm
    65 
    66   template <class Graph, class OutputIterator,
    67             class ColorMap, class DegreeMap>
    68   OutputIterator
    69   cuthill_mckee_ordering(const Graph& g,
    70                          std::deque< typename
    71                          graph_traits<Graph>::vertex_descriptor > vertex_queue,
    72                          OutputIterator permutation, 
    73                          ColorMap color, DegreeMap degree)
    74   {
    75 
    76     //create queue, visitor...don't forget namespaces!
    77     typedef typename property_traits<DegreeMap>::value_type ds_type;
    78     typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
    79     typedef typename boost::sparse::sparse_ordering_queue<Vertex> queue;
    80     typedef typename detail::bfs_rcm_visitor<OutputIterator, queue, DegreeMap> Visitor;
    81     typedef typename property_traits<ColorMap>::value_type ColorValue;
    82     typedef color_traits<ColorValue> Color;
    83 
    84 
    85     queue Q;
    86 
    87     //create a bfs_rcm_visitor as defined above
    88     Visitor     vis(&permutation, &Q, degree);
    89 
    90     typename graph_traits<Graph>::vertex_iterator ui, ui_end;    
    91 
    92     // Copy degree to pseudo_degree
    93     // initialize the color map
    94     for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui){
    95       put(color, *ui, Color::white());
    96     }
    97 
    98 
    99     while( !vertex_queue.empty() ) {
   100       Vertex s = vertex_queue.front();
   101       vertex_queue.pop_front();
   102       
   103       //call BFS with visitor
   104       breadth_first_visit(g, s, Q, vis, color);
   105     }
   106     return permutation;
   107   }
   108     
   109 
   110   // This is the case where only a single starting vertex is supplied.
   111   template <class Graph, class OutputIterator,
   112             class ColorMap, class DegreeMap>
   113   OutputIterator
   114   cuthill_mckee_ordering(const Graph& g,
   115                          typename graph_traits<Graph>::vertex_descriptor s,
   116                          OutputIterator permutation, 
   117                          ColorMap color, DegreeMap degree)
   118   {
   119 
   120     std::deque< typename graph_traits<Graph>::vertex_descriptor > vertex_queue;
   121     vertex_queue.push_front( s );
   122 
   123     return cuthill_mckee_ordering(g, vertex_queue, permutation, color, degree);
   124   
   125   }
   126   
   127 
   128   // This is the version of CM which selects its own starting vertex
   129   template < class Graph, class OutputIterator, 
   130              class ColorMap, class DegreeMap>
   131   OutputIterator 
   132   cuthill_mckee_ordering(const Graph& G, OutputIterator permutation, 
   133                          ColorMap color, DegreeMap degree)
   134   {
   135     if (vertices(G).first == vertices(G).second)
   136       return permutation;
   137 
   138     typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
   139     typedef typename boost::graph_traits<Graph>::vertex_iterator   VerIter;
   140     typedef typename property_traits<ColorMap>::value_type ColorValue;
   141     typedef color_traits<ColorValue> Color;
   142 
   143     std::deque<Vertex>      vertex_queue;
   144 
   145     // Mark everything white
   146     BGL_FORALL_VERTICES_T(v, G, Graph) put(color, v, Color::white());
   147 
   148     // Find one vertex from each connected component 
   149     BGL_FORALL_VERTICES_T(v, G, Graph) {
   150       if (get(color, v) == Color::white()) {
   151         depth_first_visit(G, v, dfs_visitor<>(), color);
   152         vertex_queue.push_back(v);
   153       }
   154     }
   155 
   156     // Find starting nodes for all vertices
   157     // TBD: How to do this with a directed graph?
   158     for (typename std::deque<Vertex>::iterator i = vertex_queue.begin();
   159          i != vertex_queue.end(); ++i)
   160       *i = find_starting_node(G, *i, color, degree);
   161     
   162     return cuthill_mckee_ordering(G, vertex_queue, permutation,
   163                                   color, degree);
   164   }
   165 
   166   template<typename Graph, typename OutputIterator, typename VertexIndexMap>
   167   OutputIterator 
   168   cuthill_mckee_ordering(const Graph& G, OutputIterator permutation, 
   169                          VertexIndexMap index_map)
   170   {
   171     if (vertices(G).first == vertices(G).second)
   172       return permutation;
   173     
   174     typedef out_degree_property_map<Graph> DegreeMap;
   175     std::vector<default_color_type> colors(num_vertices(G));
   176     return cuthill_mckee_ordering(G, permutation, 
   177                                   make_iterator_property_map(&colors[0], 
   178                                                              index_map,
   179                                                              colors[0]),
   180                                   make_out_degree_map(G));
   181   }
   182 
   183   template<typename Graph, typename OutputIterator>
   184   inline OutputIterator 
   185   cuthill_mckee_ordering(const Graph& G, OutputIterator permutation)
   186   { return cuthill_mckee_ordering(G, permutation, get(vertex_index, G)); }
   187 } // namespace boost
   188 
   189 
   190 #endif // BOOST_GRAPH_CUTHILL_MCKEE_HPP