|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r71880 - in sandbox-branches/geometry/index_080_new: boost/geometry/extensions/index/rtree boost/geometry/extensions/index/rtree/quadratic boost/geometry/extensions/index/rtree/rstar tests
From: adam.wulkiewicz_at_[hidden]
Date: 2011-05-11 17:15:01
Author: awulkiew
Date: 2011-05-11 17:15:00 EDT (Wed, 11 May 2011)
New Revision: 71880
URL: http://svn.boost.org/trac/boost/changeset/71880
Log:
rstar partially implemented
Added:
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/redistribute_elements.hpp (contents, props changed)
Text files modified:
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/quadratic/redistribute_elements.hpp | 2
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/choose_next_node.hpp | 98 ++++-----------------------------------
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/rstar.hpp | 3
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree.hpp | 3 -
sandbox-branches/geometry/index_080_new/tests/additional_sizes_and_times.cpp | 7 +-
5 files changed, 17 insertions(+), 96 deletions(-)
Modified: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/quadratic/redistribute_elements.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/quadratic/redistribute_elements.hpp (original)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/quadratic/redistribute_elements.hpp 2011-05-11 17:15:00 EDT (Wed, 11 May 2011)
@@ -12,8 +12,6 @@
#include <algorithm>
-#include <boost/tuple/tuple.hpp>
-
#include <boost/geometry/extensions/index/algorithms/area.hpp>
#include <boost/geometry/extensions/index/algorithms/union_area.hpp>
Modified: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/choose_next_node.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/choose_next_node.hpp (original)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/choose_next_node.hpp 2011-05-11 17:15:00 EDT (Wed, 11 May 2011)
@@ -34,7 +34,7 @@
typedef typename rtree::internal_node<Value, Box, rstar_tag>::type internal_node;
typedef typename rtree::leaf<Value, Box, rstar_tag>::type leaf;
- typedef typename internal_node::children_type children_type;
+ typedef typename rtree::elements_type<internal_node>::type children_type;
typedef typename index::default_area_result<Box>::type area_type;
typedef typename index::default_overlap_result<Box>::type overlap_type;
@@ -43,25 +43,26 @@
template <typename Indexable>
static inline size_t apply(internal_node & n, Indexable const& indexable)
{
- assert(!n.children.empty());
+ children_type & children = rtree::elements_get(n);
+ assert(!children.empty());
bool has_leaves = boost::apply_visitor(
visitors::is_leaf<Value, Box, rstar_tag>(),
- *n.children.front().second);
+ *children.front().second);
if ( has_leaves )
return branch_impl(n, indexable);
- //return impl<branch_areas>(n, indexable);
else
return internal_node_impl(n, indexable);
- //return impl<internal_node_areas>(n, indexable);
}
private:
template <typename Indexable>
static inline size_t branch_impl(internal_node & n, Indexable const& indexable)
{
- size_t children_count = n.children.size();
+ children_type & children = rtree::elements_get(n);
+ size_t children_count = children.size();
+
// overlaps values of all nodes' boxes,
// overlaps and areas of extended boxes are stored at indexes i + children_count
std::vector<overlap_type> overlaps(children_count * 2, overlap_type(0));
@@ -70,7 +71,7 @@
for (size_t i = 0 ; i < children_count ; ++i )
{
typedef typename children_type::value_type child_type;
- child_type const& ch_i = n.children[i];
+ child_type const& ch_i = children[i];
Box ch_ext;
// calculate expanded box fo node ch_i
@@ -82,7 +83,7 @@
for (size_t j = i + 1 ; j < children_count ; ++j )
{
- child_type const& ch_j = n.children[j];
+ child_type const& ch_j = children[j];
// add overlap of both boxes
overlap_type ovl = index::overlap(ch_i.first, ch_j.first);
@@ -128,7 +129,8 @@
template <typename Indexable>
static inline size_t internal_node_impl(internal_node & n, Indexable const& indexable)
{
- size_t children_count = n.children.size();
+ children_type & children = rtree::elements_get(n);
+ size_t children_count = children.size();
// choose index with smallest area change or smallest area
size_t choosen_index = 0;
@@ -139,7 +141,7 @@
for ( size_t i = 0 ; i < children_count ; ++i )
{
typedef typename children_type::value_type child_type;
- child_type const& ch_i = n.children[i];
+ child_type const& ch_i = children[i];
Box ch_exp;
geometry::convert(ch_i.first, ch_exp);
@@ -159,82 +161,6 @@
return choosen_index;
}
-
- //template <typename Areas, typename Indexable>
- //static inline size_t impl(internal_node & n, Indexable const& indexable)
- //{
- // typedef typename children_type::iterator children_iterator;
-
- // //assert(!n.children.empty());
-
- // children_iterator temp_it = n.children.begin();
- // children_iterator child_it = temp_it;
- // Areas min_areas(n.children, child_it, indexable);
-
- // for (children_iterator it = ++temp_it;
- // it != n.children.end(); ++it)
- // {
- // Areas areas(n.children, it, indexable);
-
- // if ( areas < min_areas )
- // {
- // child_it = it;
- // min_areas = areas;
- // }
- // }
-
- // return child_it - n.children.begin();
- //}
-
- //struct branch_areas
- //{
- // typedef typename index::area_result<Box>::type area_type;
-
- // template <typename Indexable>
- // inline branch_areas(children_type const& ch, typename children_type::iterator const& k_it, Indexable const& indexable)
- // {
- // overlap_area = 0;
- // for (typename children_type::const_iterator it = ch.begin(); it != ch.end(); ++it)
- // if ( it != k_it )
- // overlap_area += index::overlap(k_it->first, it->first);
-
- // area = index::area(k_it->first);
-
- // diff_area = index::union_area(k_it->first, indexable) - area;
- // }
-
- // inline bool operator<(branch_areas &a) const
- // {
- // return overlap_area < a.overlap_area ||
- // ( overlap_area == a.overlap_area && diff_area < a.diff_area ) ||
- // ( diff_area == a.diff_area && area < a.area );
- // }
-
- // area_type overlap_area;
- // area_type diff_area;
- // area_type area;
- //};
-
- //struct internal_node_areas
- //{
- // typedef typename area_result<Box>::type area_type;
-
- // template <typename Indexable>
- // inline internal_node_areas(children_type const&, typename children_type::iterator const& k_it, Indexable const& indexable)
- // {
- // area = index::area(k_it->first);
- // diff_area = index::union_area(k_it->first, indexable) - area;
- // }
-
- // inline bool operator<(internal_node_areas &a) const
- // {
- // return diff_area < a.diff_area ||
- // ( diff_area == a.diff_area && area < a.area );
- // }
-
- // area_type diff_area;
- // area_type area;
- //};
};
} // namespace detail
Added: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/redistribute_elements.hpp
==============================================================================
--- (empty file)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/redistribute_elements.hpp 2011-05-11 17:15:00 EDT (Wed, 11 May 2011)
@@ -0,0 +1,212 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Boost.Index - R-tree quadratic split algorithm implementation
+//
+// Copyright 2011 Adam Wulkiewicz.
+// 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)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_REDISTRIBUTE_ELEMENTS_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_REDISTRIBUTE_ELEMENTS_HPP
+
+#include <algorithm>
+
+#include <boost/geometry/extensions/index/algorithms/area.hpp>
+#include <boost/geometry/extensions/index/algorithms/union_area.hpp>
+
+#include <boost/geometry/extensions/index/rtree/node.hpp>
+#include <boost/geometry/extensions/index/rtree/visitors/insert.hpp>
+#include <boost/geometry/extensions/index/rtree/visitors/is_leaf.hpp>
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail { namespace rtree { namespace visitors {
+
+namespace detail {
+
+template <typename Value, typename Translator, typename Box>
+struct redistribute_elements<Value, Translator, Box, rstar_tag>
+{
+ typedef typename rtree::node<Value, Box, rstar_tag>::type node;
+ typedef typename rtree::internal_node<Value, Box, rstar_tag>::type internal_node;
+ typedef typename rtree::leaf<Value, Box, rstar_tag>::type leaf;
+
+ typedef typename index::default_area_result<Box>::type area_type;
+
+ template <typename Node>
+ static inline void apply(Node & n,
+ Node & second_node,
+ Box & box1,
+ Box & box2,
+ size_t min_elems,
+ size_t max_elems,
+ Translator const& tr)
+ {
+ typedef typename rtree::elements_type<Node>::type elements_type;
+ typedef typename elements_type::value_type element_type;
+ typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
+ typedef typename index::traits::coordinate_type<indexable_type>::type coordinate_type;
+
+ // copy original elements
+ elements_type elements_copy = rtree::elements_get(n);
+
+ // calculate initial seeds
+ size_t seed1 = 0;
+ size_t seed2 = 0;
+ quadratic::pick_seeds<elements_type, Translator, Box>::apply(elements_copy, tr, seed1, seed2);
+
+ // prepare nodes' elements containers
+ elements_type & elements1 = rtree::elements_get(n);
+ elements_type & elements2 = rtree::elements_get(second_node);
+ elements1.clear();
+ assert(elements2.empty());
+
+ // add seeds
+ elements1.push_back(elements_copy[seed1]);
+ elements2.push_back(elements_copy[seed2]);
+
+ // calculate boxes
+ geometry::convert(rtree::element_indexable(elements_copy[seed1], tr), box1);
+ geometry::convert(rtree::element_indexable(elements_copy[seed2], tr), box2);
+
+ // remove seeds
+ if (seed1 < seed2)
+ {
+ elements_copy.erase(elements_copy.begin() + seed2);
+ elements_copy.erase(elements_copy.begin() + seed1);
+ }
+ else
+ {
+ elements_copy.erase(elements_copy.begin() + seed1);
+ elements_copy.erase(elements_copy.begin() + seed2);
+ }
+
+ // initialize areas
+ area_type area1 = index::area(box1);
+ area_type area2 = index::area(box2);
+
+ size_t remaining = elements_copy.size();
+
+ // redistribute the rest of the elements
+ while ( !elements_copy.empty() )
+ {
+ typename elements_type::reverse_iterator el_it = elements_copy.rbegin();
+ bool insert_into_group1 = false;
+
+ size_t elements1_count = elements1.size();
+ size_t elements2_count = elements2.size();
+
+ // if there is small number of elements left and the number of elements in node is lesser than min_elems
+ // just insert them to this node
+ if ( elements1_count + remaining <= min_elems )
+ {
+ insert_into_group1 = true;
+ }
+ else if ( elements2_count + remaining <= min_elems )
+ {
+ insert_into_group1 = false;
+ }
+ // insert the best element
+ else
+ {
+ // find element with minimum groups areas increses differences
+ area_type area_increase1 = 0;
+ area_type area_increase2 = 0;
+ el_it = pick_next(elements_copy.rbegin(), elements_copy.rend(),
+ box1, box2, area1, area2, tr,
+ area_increase1, area_increase2);
+
+ if ( area_increase1 < area_increase2 ||
+ ( area_increase1 == area_increase2 && area1 < area2 ) ||
+ ( area1 == area2 && elements1_count <= elements2_count ) )
+ {
+ insert_into_group1 = true;
+ }
+ else
+ {
+ insert_into_group1 = false;
+ }
+ }
+
+ // move element to the choosen group
+ element_type const& elem = *el_it;
+ indexable_type const& indexable = rtree::element_indexable(elem, tr);
+
+ if ( insert_into_group1 )
+ {
+ elements1.push_back(elem);
+ geometry::expand(box1, indexable);
+ area1 = index::area(box1);
+ }
+ else
+ {
+ elements2.push_back(elem);
+ geometry::expand(box2, indexable);
+ area2 = index::area(box2);
+ }
+
+ assert(!elements_copy.empty());
+ elements_copy.erase(--el_it.base());
+
+ assert(0 < remaining);
+ --remaining;
+ }
+ }
+
+ // sprawdzic szukanie najmniejszego powiekszenia wezla dla grupy1 i grupy2
+
+ template <typename It>
+ static inline It pick_next(It first, It last,
+ Box const& box1, Box const& box2,
+ area_type const& area1, area_type const& area2,
+ Translator const& tr,
+ area_type & out_area_increase1, area_type & out_area_increase2)
+ {
+ typedef typename boost::iterator_value<It>::type element_type;
+ typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
+
+ area_type greatest_area_incrase_diff = 0;
+ It out_it = first;
+ out_area_increase1 = 0;
+ out_area_increase2 = 0;
+
+ // find element with greatest difference between increased group's boxes areas
+ for ( It el_it = first ; el_it != last ; ++el_it )
+ {
+ indexable_type const& indexable = rtree::element_indexable(*el_it, tr);
+
+ // calculate enlarged boxes and areas
+ Box enlarged_box1(box1);
+ Box enlarged_box2(box2);
+ geometry::expand(enlarged_box1, indexable);
+ geometry::expand(enlarged_box2, indexable);
+ area_type enlarged_area1 = index::area(enlarged_box1);
+ area_type enlarged_area2 = index::area(enlarged_box2);
+
+ area_type area_incrase1 = (enlarged_area1 - area1);
+ area_type area_incrase2 = (enlarged_area2 - area2);
+
+ area_type area_incrase_diff = area_incrase1 < area_incrase2 ?
+ area_incrase2 - area_incrase1 : area_incrase1 - area_incrase2;
+
+ if ( greatest_area_incrase_diff < area_incrase_diff )
+ {
+ greatest_area_incrase_diff = area_incrase_diff;
+ out_it = el_it;
+ out_area_increase1 = area_incrase1;
+ out_area_increase2 = area_incrase2;
+ }
+ }
+
+ return out_it;
+ }
+};
+
+} // namespace detail
+
+}}} // namespace detail::rtree::visitors
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_REDISTRIBUTE_ELEMENTS_HPP
Modified: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/rstar.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/rstar.hpp (original)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/rstar.hpp 2011-05-11 17:15:00 EDT (Wed, 11 May 2011)
@@ -17,7 +17,6 @@
}}} // namespace boost::geometry::index
#include <boost/geometry/extensions/index/rtree/rstar/choose_next_node.hpp>
-
-#include <boost/geometry/extensions/index/rtree/rstar/insert.hpp>
+#include <boost/geometry/extensions/index/rtree/rstar/redistribute_elements.hpp>
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_RSTAR_HPP
Modified: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree.hpp (original)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree.hpp 2011-05-11 17:15:00 EDT (Wed, 11 May 2011)
@@ -21,10 +21,7 @@
#include <boost/geometry/extensions/index/rtree/visitors/remove.hpp>
#include <boost/geometry/extensions/index/rtree/linear/linear.hpp>
-
#include <boost/geometry/extensions/index/rtree/quadratic/quadratic.hpp>
-
-// TODO: awulkiew - correct implementation
//#include <boost/geometry/extensions/index/rtree/rstar/rstar.hpp>
namespace boost { namespace geometry { namespace index {
Modified: sandbox-branches/geometry/index_080_new/tests/additional_sizes_and_times.cpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/tests/additional_sizes_and_times.cpp (original)
+++ sandbox-branches/geometry/index_080_new/tests/additional_sizes_and_times.cpp 2011-05-11 17:15:00 EDT (Wed, 11 May 2011)
@@ -6,7 +6,7 @@
#include <boost/timer.hpp>
#include <boost/foreach.hpp>
-#include <boost/geometry/extensions/index/rtree/visitors/save.hpp>
+//#include <boost/geometry/extensions/index/rtree/visitors/save.hpp>
int main()
{
@@ -19,6 +19,7 @@
typedef bg::model::box<P> B;
typedef bgi::rtree<std::pair<B, size_t>, bgi::default_parameter, bgi::linear_tag> RT;
//typedef bgi::rtree<std::pair<B, size_t>, bgi::default_parameter, bgi::quadratic_tag> RT;
+ //typedef bgi::rtree<std::pair<B, size_t>, bgi::default_parameter, bgi::rstar_tag> RT;
std::ifstream file_cfg("config.txt");
size_t max_elems = 4;
@@ -60,7 +61,7 @@
std::cout << "time: " << tim.elapsed() << "s\n";
}
- if ( save_ch == 's' )
+ /*if ( save_ch == 's' )
{
std::cout << "saving...\n";
std::ofstream file("save_new.txt", std::ofstream::trunc);
@@ -73,7 +74,7 @@
> saving_v(file, t.get_translator());
t.apply_visitor(saving_v);
std::cout << "saved...\n";
- }
+ }*/
{
std::cout << "searching time test...\n";
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk