kd tree java_Kd-Tree算法原理和开源实现代码

本文介绍一种用于高维空间中的高速近期邻和近似近期邻查找技术——Kd-Tree(Kd树)。

Kd-Tree,即K-dimensional

tree,是一种高维索引树形数据结构,经常使用于在大规模的高维数据空间进行近期邻查找(Nearest Neighbor)和近似近期邻查找(Approximate Nearest Neighbor),比如图像检索和识别中的高维图像特征向量的K近邻查找与匹配。本文首先介绍Kd-Tree的基本原理,然后对基于BBF的近似查找方法进行介绍。最后给出一些參考文献和开源实现代码。

一、Kd-tree

Kd-Tree。即K-dimensional

tree,是一棵二叉树,树中存储的是一些K维数据。在一个K维数据集合上构建一棵Kd-Tree代表了对该K维数据集合构成的K维空间的一个划分。即树中的每一个结点就相应了一个K维的超矩形区域(Hyperrectangle)。

在介绍Kd-tree的相关算法前。我们先回想一下二叉查找树(Binary

Search Tree)的相关概念和算法。

二叉查找树(Binary Search

Tree,BST)。是具有例如以下性质的二叉树(来自wiki):

1)若它的左子树不为空。则左子树上全部结点的值均小于它的根结点的值;

2)若它的右子树不为空,则右子树上全部结点的值均大于它的根结点的值;

3)它的左、右子树也分别为二叉排序树;

比如,图1中是一棵二叉查找树,其满足BST的性质。

0e053076f0b33cb4aa2dcc245fd340df.png

图1 二叉查找树(来源:Wiki)

给定一个1维数据集合。如何构建一棵BST树呢?依据BST的性质就能够创建,即将数据点一个一个插入到BST树中,插入后的树仍然是BST树。即根结点的左子树中全部结点的值均小于根结点的值,而根结点的右子树中全部结点的值均大于根结点的值。

将一个1维数据集用一棵BST树存储后,当我们想要查询某个数据是否位于该数据集合中时。仅仅须要将查询数据与结点值进行比較然后选择相应的子树继续往下查找就可以,查找的平均时间复杂度为:O(logN),最坏的情况下是O(N)。

假设我们要处理的对象集合是一个K维空间中的数据集,那么是否也能够构建一棵类似于1维空间中的二叉查找树呢?答案是肯定的。仅仅只是推广到K维空间后,创建二叉树和查询二叉树的算法会有一些对应的变化(后面会介绍到两者的差别),这就是以下我们要介绍的Kd-tree算法。

如何构造一棵Kd-tree?

对于Kd-tree这样一棵二叉树,我们首先须要确定如何划分左子树和右子树。即一个K维数据是根据什么被划分到左子树或右子树的。

在构造1维BST树时,一个1维数据依据其与树的根结点和中间结点进行大小比較的结果来决定是划分到左子树还是右子树。同理。我们也能够依照这种方式,将一个K维数据与Kd-tree的根结点和中间结点进行比較。仅仅只是不是对K维数据进行总体的比較,而是选择某一个维度Di。然后比較两个K维数在该维度Di上的大小关系。即每次选择一个维度Di来对K维数据进行划分,相当于用一个垂直于该维度Di的超平面将K维数据空间一分为二。平面一边的全部K维数据在Di维度上的值小于平面还有一边的全部K维数据相应维度上的值。也就是说。我们每选择一个维度进行如上的划分,就会将K维数据空间划分为两个部分。假设我们继续分别对这两个子K维空间进行如上的划分。又会得到新的子空间,对新的子空间又继续划分,反复以上过程直到每一个子空间都不能再划分为止。以上就是构造Kd-Tree的过程,上述过程中涉及到两个重要的问题:1)每次对子空间的划分时。如何确定在哪个维度上进行划分;2)在某个维度上进行划分时,如何确保在这一维度上的划分得到的两个子集合的数量尽量相等。即左子树和右子树中的结点个数尽量相等。

问题1: 每次对子空间的划分时ÿ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值