smallest_last_ordering.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. //=======================================================================
  2. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  3. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. // Revision History:
  10. // 17 March 2006: Fixed a bug: when updating the degree a vertex
  11. // could be moved to a wrong bucket. (Roman Dementiev)
  12. //
  13. #ifndef BOOST_SMALLEST_LAST_VERTEX_ORDERING_HPP
  14. #define BOOST_SMALLEST_LAST_VERTEX_ORDERING_HPP
  15. /*
  16. The smallest-last ordering is defined for the loopless graph G with
  17. vertices a(j), j = 1,2,...,n where a(j) is the j-th column of A and
  18. with edge (a(i),a(j)) if and only if columns i and j have a
  19. non-zero in the same row position. The smallest-last ordering is
  20. determined recursively by letting list(k), k = n,...,1 be a column
  21. with least degree in the subgraph spanned by the un-ordered
  22. columns.
  23. */
  24. #include <vector>
  25. #include <algorithm>
  26. #include <boost/config.hpp>
  27. #include <boost/graph/graph_traits.hpp>
  28. #include <boost/graph/properties.hpp>
  29. #include <boost/pending/bucket_sorter.hpp>
  30. namespace boost
  31. {
  32. template < class VertexListGraph, class Order, class Degree, class Marker >
  33. void smallest_last_vertex_ordering(
  34. const VertexListGraph& G, Order order, Degree degree, Marker marker)
  35. {
  36. typedef typename boost::graph_traits< VertexListGraph > GraphTraits;
  37. typedef typename GraphTraits::vertex_descriptor Vertex;
  38. // typedef typename GraphTraits::size_type size_type;
  39. typedef std::size_t size_type;
  40. const size_type num = num_vertices(G);
  41. typedef
  42. typename boost::property_map< VertexListGraph, vertex_index_t >::type
  43. ID;
  44. typedef bucket_sorter< size_type, Vertex, Degree, ID > BucketSorter;
  45. BucketSorter degree_bucket_sorter(num, num, degree, get(vertex_index, G));
  46. smallest_last_vertex_ordering(
  47. G, order, degree, marker, degree_bucket_sorter);
  48. }
  49. template < class VertexListGraph, class Order, class Degree, class Marker,
  50. class BucketSorter >
  51. void smallest_last_vertex_ordering(const VertexListGraph& G, Order order,
  52. Degree degree, Marker marker, BucketSorter& degree_buckets)
  53. {
  54. typedef typename boost::graph_traits< VertexListGraph > GraphTraits;
  55. typedef typename GraphTraits::vertex_descriptor Vertex;
  56. // typedef typename GraphTraits::size_type size_type;
  57. typedef std::size_t size_type;
  58. const size_type num = num_vertices(G);
  59. typename GraphTraits::vertex_iterator v, vend;
  60. for (boost::tie(v, vend) = vertices(G); v != vend; ++v)
  61. {
  62. put(marker, *v, num);
  63. put(degree, *v, out_degree(*v, G));
  64. degree_buckets.push(*v);
  65. }
  66. size_type minimum_degree = 0;
  67. size_type current_order = num - 1;
  68. while (1)
  69. {
  70. typedef typename BucketSorter::stack MDStack;
  71. MDStack minimum_degree_stack = degree_buckets[minimum_degree];
  72. while (minimum_degree_stack.empty())
  73. minimum_degree_stack = degree_buckets[++minimum_degree];
  74. Vertex node = minimum_degree_stack.top();
  75. put(order, current_order, node);
  76. if (current_order == 0) // find all vertices
  77. break;
  78. minimum_degree_stack.pop();
  79. put(marker, node, 0); // node has been ordered.
  80. typename GraphTraits::adjacency_iterator v, vend;
  81. for (boost::tie(v, vend) = adjacent_vertices(node, G); v != vend; ++v)
  82. if (get(marker, *v) > current_order)
  83. { //*v is unordered vertex
  84. put(marker, *v,
  85. current_order); // mark the columns adjacent to node
  86. // delete *v from the bucket sorter
  87. degree_buckets.remove(*v);
  88. // It is possible minimum degree goes down
  89. // Here we keep tracking it.
  90. put(degree, *v, get(degree, *v) - 1);
  91. BOOST_USING_STD_MIN();
  92. minimum_degree = min BOOST_PREVENT_MACRO_SUBSTITUTION(
  93. minimum_degree, get(degree, *v));
  94. // reinsert *v in the bucket sorter with the new degree
  95. degree_buckets.push(*v);
  96. }
  97. current_order--;
  98. }
  99. // at this point, order[i] = v_i;
  100. }
  101. template < class VertexListGraph, class Order >
  102. void smallest_last_vertex_ordering(const VertexListGraph& G, Order order)
  103. {
  104. typedef typename graph_traits< VertexListGraph >::vertex_descriptor
  105. vertex_descriptor;
  106. typedef typename graph_traits< VertexListGraph >::degree_size_type
  107. degree_size_type;
  108. smallest_last_vertex_ordering(G, order,
  109. make_shared_array_property_map(
  110. num_vertices(G), degree_size_type(0), get(vertex_index, G)),
  111. make_shared_array_property_map(
  112. num_vertices(G), (std::size_t)(0), get(vertex_index, G)));
  113. }
  114. template < class VertexListGraph >
  115. std::vector< typename graph_traits< VertexListGraph >::vertex_descriptor >
  116. smallest_last_vertex_ordering(const VertexListGraph& G)
  117. {
  118. std::vector< typename graph_traits< VertexListGraph >::vertex_descriptor >
  119. o(num_vertices(G));
  120. smallest_last_vertex_ordering(G,
  121. make_iterator_property_map(
  122. o.begin(), typed_identity_property_map< std::size_t >()));
  123. return o;
  124. }
  125. }
  126. #endif