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