rtree: margin() renamed to comparable_margin(), other/simpler algorithm used, 3d_benchmark added

[SVN r83449]
This commit is contained in:
Adam Wulkiewicz 2013-03-15 18:49:46 +00:00
parent 453af42c4b
commit f850426692
3 changed files with 244 additions and 54 deletions

161
example/3d_benchmark.cpp Normal file
View File

@ -0,0 +1,161 @@
// Boost.Geometry Index
// Additional tests
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <iostream>
#include <boost/geometry/index/rtree.hpp>
#include <boost/chrono.hpp>
#include <boost/foreach.hpp>
#include <boost/random.hpp>
int main()
{
namespace bg = boost::geometry;
namespace bgi = bg::index;
typedef boost::chrono::thread_clock clock_t;
typedef boost::chrono::duration<float> dur_t;
size_t values_count = 500000;
size_t queries_count = 200000;
std::vector< boost::tuple<float, float, float> > coords;
//randomize values
{
boost::mt19937 rng;
//rng.seed(static_cast<unsigned int>(std::time(0)));
float max_val = static_cast<float>(values_count / 2);
boost::uniform_real<float> range(-max_val, max_val);
boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > rnd(rng, range);
coords.reserve(values_count);
std::cout << "randomizing data\n";
for ( size_t i = 0 ; i < values_count ; ++i )
{
coords.push_back(boost::make_tuple(rnd(), rnd(), rnd()));
}
std::cout << "randomized\n";
}
typedef bg::model::point<float, 3, bg::cs::cartesian> P;
typedef bg::model::box<P> B;
//typedef bgi::rtree<B, bgi::linear<32, 8> > RT;
//typedef bgi::rtree<B, bgi::quadratic<32, 8> > RT;
typedef bgi::rtree<B, bgi::rstar<8, 3> > RT;
std::cout << "sizeof rtree: " << sizeof(RT) << std::endl;
for (;;)
{
RT t;
// inserting test
{
clock_t::time_point start = clock_t::now();
for (size_t i = 0 ; i < values_count ; ++i )
{
float x = boost::get<0>(coords[i]);
float y = boost::get<1>(coords[i]);
float z = boost::get<2>(coords[i]);
B b(P(x - 0.5f, y - 0.5f, z - 0.5f), P(x + 0.5f, y + 0.5f, z + 0.5f));
t.insert(b);
}
dur_t time = clock_t::now() - start;
std::cout << time << " - insert " << values_count << '\n';
}
std::vector<B> result;
result.reserve(100);
B result_one;
{
clock_t::time_point start = clock_t::now();
size_t temp = 0;
for (size_t i = 0 ; i < queries_count ; ++i )
{
float x = boost::get<0>(coords[i]);
float y = boost::get<1>(coords[i]);
float z = boost::get<2>(coords[i]);
result.clear();
t.query(bgi::intersects(B(P(x - 10, y - 10, z - 10), P(x + 10, y + 10, z + 10))), std::back_inserter(result));
temp += result.size();
}
dur_t time = clock_t::now() - start;
std::cout << time << " - query(B) " << queries_count << " found " << temp << '\n';
}
{
clock_t::time_point start = clock_t::now();
size_t temp = 0;
for (size_t i = 0 ; i < queries_count / 2 ; ++i )
{
float x1 = boost::get<0>(coords[i]);
float y1 = boost::get<1>(coords[i]);
float z1 = boost::get<2>(coords[i]);
float x2 = boost::get<0>(coords[i+1]);
float y2 = boost::get<1>(coords[i+1]);
float z2 = boost::get<2>(coords[i+1]);
float x3 = boost::get<0>(coords[i+2]);
float y3 = boost::get<1>(coords[i+2]);
float z3 = boost::get<2>(coords[i+2]);
result.clear();
t.query(
bgi::intersects(B(P(x1 - 10, y1 - 10, z1 - 10), P(x1 + 10, y1 + 10, z1 + 10)))
&&
!bgi::within(B(P(x2 - 10, y2 - 10, z2 - 10), P(x2 + 10, y2 + 10, z2 + 10)))
&&
!bgi::overlaps(B(P(x3 - 10, y3 - 10, z3 - 10), P(x3 + 10, y3 + 10, z3 + 10)))
,
std::back_inserter(result)
);
temp += result.size();
}
dur_t time = clock_t::now() - start;
std::cout << time << " - query(i && !w && !o) " << queries_count << " found " << temp << '\n';
}
result.clear();
{
clock_t::time_point start = clock_t::now();
size_t temp = 0;
for (size_t i = 0 ; i < queries_count / 10 ; ++i )
{
float x = boost::get<0>(coords[i]) - 100;
float y = boost::get<1>(coords[i]) - 100;
float z = boost::get<2>(coords[i]) - 100;
result.clear();
temp += t.query(bgi::nearest(P(x, y, z), 5), std::back_inserter(result));
}
dur_t time = clock_t::now() - start;
std::cout << time << " - query(nearest(P, 5)) " << (queries_count / 10) << " found " << temp << '\n';
}
{
clock_t::time_point start = clock_t::now();
for (size_t i = 0 ; i < values_count / 10 ; ++i )
{
float x = boost::get<0>(coords[i]);
float y = boost::get<1>(coords[i]);
float z = boost::get<2>(coords[i]);
B b(P(x - 0.5f, y - 0.5f, z - 0.5f), P(x + 0.5f, y + 0.5f, z + 0.5f));
t.remove(b);
}
dur_t time = clock_t::now() - start;
std::cout << time << " - remove " << values_count / 10 << '\n';
}
std::cout << "------------------------------------------------\n";
}
return 0;
}

View File

@ -22,35 +22,88 @@ struct default_margin_result
>::type type;
};
template <typename Box, size_t CurrentDimension, size_t EdgeDimension>
struct margin_for_each_edge
//template <typename Box, size_t CurrentDimension, size_t EdgeDimension>
//struct margin_for_each_edge
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
// BOOST_STATIC_ASSERT(0 < EdgeDimension);
//
// static inline typename default_margin_result<Box>::type apply(Box const& b)
// {
// return margin_for_each_edge<Box, CurrentDimension, EdgeDimension - 1>::apply(b) *
// ( geometry::get<max_corner, EdgeDimension - 1>(b) - geometry::get<min_corner, EdgeDimension - 1>(b) );
// }
//};
//
//template <typename Box, size_t CurrentDimension>
//struct margin_for_each_edge<Box, CurrentDimension, CurrentDimension>
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
//
// static inline typename default_margin_result<Box>::type apply(Box const& b)
// {
// return margin_for_each_edge<Box, CurrentDimension, CurrentDimension - 1>::apply(b);
// }
//};
//
//template <typename Box, size_t CurrentDimension>
//struct margin_for_each_edge<Box, CurrentDimension, 1>
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
//
// static inline typename default_margin_result<Box>::type apply(Box const& b)
// {
// return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
// }
//};
//
//template <typename Box>
//struct margin_for_each_edge<Box, 1, 1>
//{
// static inline typename default_margin_result<Box>::type apply(Box const& /*b*/)
// {
// return 1;
// }
//};
//
//template <typename Box, size_t CurrentDimension>
//struct margin_for_each_dimension
//{
// BOOST_STATIC_ASSERT(0 < CurrentDimension);
// BOOST_STATIC_ASSERT(CurrentDimension <= detail::traits::dimension<Box>::value);
//
// static inline typename default_margin_result<Box>::type apply(Box const& b)
// {
// return margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
// margin_for_each_edge<Box, CurrentDimension, detail::traits::dimension<Box>::value>::apply(b);
// }
//};
//
//template <typename Box>
//struct margin_for_each_dimension<Box, 1>
//{
// static inline typename default_margin_result<Box>::type apply(Box const& b)
// {
// return margin_for_each_edge<Box, 1, detail::traits::dimension<Box>::value>::apply(b);
// }
//};
template <typename Box, size_t CurrentDimension>
struct simple_margin_for_each_dimension
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
BOOST_STATIC_ASSERT(0 < EdgeDimension);
BOOST_STATIC_ASSERT(CurrentDimension <= detail::traits::dimension<Box>::value);
static inline typename default_margin_result<Box>::type apply(Box const& b)
{
return margin_for_each_edge<Box, CurrentDimension, EdgeDimension - 1>::apply(b) *
( geometry::get<max_corner, EdgeDimension - 1>(b) - geometry::get<min_corner, EdgeDimension - 1>(b) );
return simple_margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
geometry::get<max_corner, CurrentDimension - 1>(b) - geometry::get<min_corner, CurrentDimension - 1>(b);
}
};
template <typename Box, size_t CurrentDimension>
struct margin_for_each_edge<Box, CurrentDimension, CurrentDimension>
template <typename Box>
struct simple_margin_for_each_dimension<Box, 1>
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
static inline typename default_margin_result<Box>::type apply(Box const& b)
{
return margin_for_each_edge<Box, CurrentDimension, CurrentDimension - 1>::apply(b);
}
};
template <typename Box, size_t CurrentDimension>
struct margin_for_each_edge<Box, CurrentDimension, 1>
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
static inline typename default_margin_result<Box>::type apply(Box const& b)
{
return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
@ -58,42 +111,18 @@ struct margin_for_each_edge<Box, CurrentDimension, 1>
};
template <typename Box>
struct margin_for_each_edge<Box, 1, 1>
typename default_margin_result<Box>::type comparable_margin(Box const& b)
{
static inline typename default_margin_result<Box>::type apply(Box const& /*b*/)
{
return 1;
}
};
template <typename Box, size_t CurrentDimension>
struct margin_for_each_dimension
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
BOOST_STATIC_ASSERT(CurrentDimension <= detail::traits::dimension<Box>::value);
static inline typename default_margin_result<Box>::type apply(Box const& b)
{
return margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
margin_for_each_edge<Box, CurrentDimension, detail::traits::dimension<Box>::value>::apply(b);
}
};
template <typename Box>
struct margin_for_each_dimension<Box, 1>
{
static inline typename default_margin_result<Box>::type apply(Box const& b)
{
return margin_for_each_edge<Box, 1, detail::traits::dimension<Box>::value>::apply(b);
}
};
template <typename Box>
typename default_margin_result<Box>::type margin(Box const& b)
{
return 2 * detail::margin_for_each_dimension<Box, detail::traits::dimension<Box>::value>::apply(b);
//return detail::margin_for_each_dimension<Box, detail::traits::dimension<Box>::value>::apply(b);
return detail::simple_margin_for_each_dimension<Box, detail::traits::dimension<Box>::value>::apply(b);
}
//template <typename Box>
//typename default_margin_result<Box>::type margin(Box const& b)
//{
// return 2 * detail::margin_for_each_dimension<Box, detail::traits::dimension<Box>::value>::apply(b);
//}
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP

View File

@ -85,7 +85,7 @@ struct choose_split_axis_and_index_for_corner
Box box1 = rtree::elements_box<Box>(elements_copy.begin(), elements_copy.begin() + i, translator);
Box box2 = rtree::elements_box<Box>(elements_copy.begin() + i, elements_copy.end(), translator);
sum_of_margins += index::detail::margin(box1) + index::detail::margin(box2);
sum_of_margins += index::detail::comparable_margin(box1) + index::detail::comparable_margin(box2);
content_type ovl = index::detail::intersection_content(box1, box2);
content_type con = index::detail::content(box1) + index::detail::content(box2);