kd-tree:
k-dimensional tree is a space-partitioning data structure for organizing points in a k-dimensional space. kd-trees are a useful data structure for several applications, such as searches involving a multidimensional search key (e.g. range searches and nearest neighbor searches).
construct
function kdtree (list of points pointList, int depth)
{
if pointList is empty
return nil;
else
{
// Select axis based on depth so that axis cycles through all valid values
var int axis := depth mod k;
// Sort point list and choose median as pivot element
select median by axis from pointList; //将pointList按第axis维排序,得到中间元素
// Create node and construct subtrees
var tree_node node;
node.location := median;
node.leftChild := kdtree(points in pointList before median, depth+1);
node.rightChild := kdtree(points in pointList after median, depth+1);
return node;
}
}
Nearest neighbor search
The nearest neighbor (NN) algorithm aims to find the point in the tree which is nearest to a given input point. This search can be done efficiently by using the tree properties to quickly eliminate large portions of the search space. Searching for a nearest neighbor in a kd-tree proceeds as follows:
Generally the algorithm uses squared distances for comparison to avoid computing square roots. Additionally, it can save computation by holding the squared current best distance in a variable for comparison.
High-Dimensional Data
kd-trees are not suitable for efficiently finding the nearest neighbour in high dimensional spaces. As a general rule, if the dimensionality is k, then number of points in the data, N, should be N >> 2k. Otherwise, when kd-trees are used with high-dimensional data, most of the points in the tree will be evaluated and the efficiency is no better than exhaustive search,[3] and approximate nearest-neighbour methods are used instead.
libkdtree++ usage:
struct triplet{int d[3]; typedef int value_type;}
将triplet用到kdtree中:
template <size_t const __K, typename _Val,
typename _Acc = _Bracket_accessor<_Val>,
typename _Dist = squared_difference<typename _Acc::result_type,
typename _Acc::result_type>,
typename _Cmp = std::less<typename _Acc::result_type>,
typename _Alloc = std::allocator<_Node<_Val> > >
class KDTree
定义树: typedef KDTree::KDTree<3, triplet, std::pointer_to_binary_function<triplet,size_t,double> > tree_type;
KDTree构造函数接受一个_Acc 对象。
tree_type::_Region_ r(cc540, std::ptr_fun(tac)); //Region接受一个对象、以及访问该对象的函数 operator []
int c = src.count_within_range(r); //得到与cc540相等的对象个数
triplet cc540(7, 4, 0);
tree_type::size_type c = src.count_within_range(cc540, int(1)); //得到与cc540各维度正负1范围内的所有对象的个数