diff --git a/include/boost/graph/detail/sparse_ordering.hpp b/include/boost/graph/detail/sparse_ordering.hpp index b7bf470db..67851af08 100644 --- a/include/boost/graph/detail/sparse_ordering.hpp +++ b/include/boost/graph/detail/sparse_ordering.hpp @@ -122,7 +122,7 @@ namespace sparse inline reverse_iterator rbegin() { return this->c.rbegin(); } inline iterator end() { return this->c.end(); } inline reverse_iterator rend() { return this->c.rend(); } - inline Tp& operator[](int n) { return this->c[n]; } + inline Tp& operator[](size_type n) { return this->c[n]; } inline size_type size() { return this->c.size(); } protected: diff --git a/include/boost/graph/king_ordering.hpp b/include/boost/graph/king_ordering.hpp index 9f4411086..ee71123c1 100644 --- a/include/boost/graph/king_ordering.hpp +++ b/include/boost/graph/king_ordering.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -33,7 +34,7 @@ namespace detail { public: bfs_king_visitor(OutputIterator* iter, Buffer* b, Compare compare, - PseudoDegreeMap deg, std::vector< int > loc, VecMap color, + PseudoDegreeMap deg, std::vector< std::ptrdiff_t > loc, VecMap color, VertexIndexMap vertices) : permutation(iter) , Qptr(b) @@ -60,9 +61,10 @@ namespace detail // heap the vertices already there std::make_heap(rbegin, rend, [this](const auto& first, const auto& second) { return comp(second, first); }); - unsigned i = 0; + std::ptrdiff_t i = 0; - for (i = index_begin; i != Qptr->size(); ++i) + for (i = index_begin; i != static_cast< std::ptrdiff_t >(Qptr->size()); + ++i) { colors[get(vertex_map, (*Qptr)[i])] = 1; Qlocation[get(vertex_map, (*Qptr)[i])] = i; @@ -101,10 +103,10 @@ namespace detail protected: // this function replaces pop_heap, and tracks state information - template < typename Vertex > void percolate_down(int offset) + template < typename Vertex > void percolate_down(std::ptrdiff_t offset) { - int heap_last = index_begin + offset; - int heap_first = Qptr->size() - 1; + std::ptrdiff_t heap_last = index_begin + offset; + std::ptrdiff_t heap_first = Qptr->size() - 1; // pop_heap functionality: // swap first, last @@ -114,21 +116,21 @@ namespace detail std::swap(Qlocation[heap_first], Qlocation[heap_last]); // set drifter, children - int drifter = heap_first; - int drifter_heap = Qptr->size() - drifter; + std::ptrdiff_t drifter = heap_first; + std::ptrdiff_t drifter_heap = Qptr->size() - drifter; - int right_child_heap = drifter_heap * 2 + 1; - int right_child = Qptr->size() - right_child_heap; + std::ptrdiff_t right_child_heap = drifter_heap * 2 + 1; + std::ptrdiff_t right_child = Qptr->size() - right_child_heap; - int left_child_heap = drifter_heap * 2; - int left_child = Qptr->size() - left_child_heap; + std::ptrdiff_t left_child_heap = drifter_heap * 2; + std::ptrdiff_t left_child = Qptr->size() - left_child_heap; // check that we are staying in the heap bool valid = (right_child < heap_last) ? false : true; // pick smallest child of drifter, and keep in mind there might only // be left child - int smallest_child = (valid + std::ptrdiff_t smallest_child = (valid && get(degree, (*Qptr)[left_child]) > get(degree, (*Qptr)[right_child])) ? right_child @@ -164,17 +166,20 @@ namespace detail // this is like percolate down, but we always compare against the // parent, as there is only a single choice - template < typename Vertex > void percolate_up(int vertex, int offset) + template < typename Vertex > + void percolate_up(std::ptrdiff_t vertex, std::ptrdiff_t offset) { - int child_location = Qlocation[vertex]; - int heap_child_location = Qptr->size() - child_location; - int heap_parent_location = (int)(heap_child_location / 2); - unsigned parent_location = Qptr->size() - heap_parent_location; + std::ptrdiff_t child_location = Qlocation[vertex]; + std::ptrdiff_t heap_child_location = Qptr->size() - child_location; + std::ptrdiff_t heap_parent_location + = (std::ptrdiff_t)(heap_child_location / 2); + std::ptrdiff_t parent_location + = Qptr->size() - heap_parent_location; bool valid = (heap_parent_location != 0 && child_location > index_begin + offset - && parent_location < Qptr->size()); + && parent_location < static_cast< std::ptrdiff_t >(Qptr->size())); while (valid && comp((*Qptr)[child_location], (*Qptr)[parent_location])) @@ -189,7 +194,7 @@ namespace detail child_location = parent_location; heap_child_location = heap_parent_location; - heap_parent_location = (int)(heap_child_location / 2); + heap_parent_location = (std::ptrdiff_t)(heap_child_location / 2); parent_location = Qptr->size() - heap_parent_location; valid = (heap_parent_location != 0 && child_location > index_begin + offset); @@ -197,11 +202,11 @@ namespace detail } OutputIterator* permutation; - int index_begin; + std::ptrdiff_t index_begin; Buffer* Qptr; PseudoDegreeMap degree; Compare comp; - std::vector< int > Qlocation; + std::vector< std::ptrdiff_t > Qlocation; VecMap colors; VertexIndexMap vertex_map; }; @@ -249,7 +254,7 @@ OutputIterator king_ordering(const Graph& g, for (vertices_size_type i = 0; i < num_vertices(g); i++) colors[i] = 0; - std::vector< int > loc(num_vertices(g)); + std::vector< std::ptrdiff_t > loc(num_vertices(g)); // create the visitor Visitor vis(&permutation, &Q, comp, pseudo_degree, loc, colors, index_map); diff --git a/test/king_ordering.cpp b/test/king_ordering.cpp index 11388ee76..ea6be3b19 100644 --- a/test/king_ordering.cpp +++ b/test/king_ordering.cpp @@ -15,6 +15,7 @@ #include #include #include +#include /* Sample Output @@ -69,7 +70,27 @@ int main(int, char*[]) property_map< Graph, vertex_index_t >::type index_map = get(vertex_index, G); - std::cout << "original bandwidth: " << bandwidth(G) << std::endl; + const size_type n = num_vertices(G); + auto assert_valid_permutation + = [&index_map, n](const std::vector< Vertex >& order) { + BOOST_TEST(order.size() == n); + std::vector< bool > seen(n, false); + for (std::size_t k = 0; k < order.size(); ++k) + { + size_type idx = index_map[order[k]]; + BOOST_TEST(idx < n); + if (idx < n) + { + BOOST_TEST(!seen[idx]); + seen[idx] = true; + } + } + for (size_type k = 0; k < n; ++k) + BOOST_TEST(seen[k]); + }; + + const size_type original_bw = bandwidth(G); + std::cout << "original bandwidth: " << original_bw << std::endl; std::vector< Vertex > inv_perm(num_vertices(G)); std::vector< size_type > perm(num_vertices(G)); @@ -87,11 +108,11 @@ int main(int, char*[]) for (size_type c = 0; c != inv_perm.size(); ++c) perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, - make_iterator_property_map( - &perm[0], index_map, perm[0])) - << std::endl; + size_type bw = bandwidth( + G, make_iterator_property_map(&perm[0], index_map, perm[0])); + std::cout << " bandwidth: " << bw << std::endl; + assert_valid_permutation(inv_perm); + BOOST_TEST(bw <= original_bw); } { Vertex s = vertex(0, G); @@ -107,11 +128,11 @@ int main(int, char*[]) for (size_type c = 0; c != inv_perm.size(); ++c) perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, - make_iterator_property_map( - &perm[0], index_map, perm[0])) - << std::endl; + size_type bw = bandwidth( + G, make_iterator_property_map(&perm[0], index_map, perm[0])); + std::cout << " bandwidth: " << bw << std::endl; + assert_valid_permutation(inv_perm); + BOOST_TEST(bw <= original_bw); } { @@ -127,11 +148,11 @@ int main(int, char*[]) for (size_type c = 0; c != inv_perm.size(); ++c) perm[index_map[inv_perm[c]]] = c; - std::cout << " bandwidth: " - << bandwidth(G, - make_iterator_property_map( - &perm[0], index_map, perm[0])) - << std::endl; + size_type bw = bandwidth( + G, make_iterator_property_map(&perm[0], index_map, perm[0])); + std::cout << " bandwidth: " << bw << std::endl; + assert_valid_permutation(inv_perm); + BOOST_TEST(bw <= original_bw); } - return 0; + return boost::report_errors(); }