amcl 之kd_tree改进算法

Kd-tree在维度较小时(比如:K≤30),算法的查找效率非常高,然而当Kd-tree用于对高维数据(比如:K≥100)进行索引和查找时,就面临着维数灾难(curse of dimension)问题,查找效率会随着维度的添加而迅速下降。

通常。实际应用中,我们经常处理的数据都具有高维的特点,比如在图像检索和识别中。每张图像通经常使用一个几百维的向量来表示,每一个特征点的局部特征用一个高维向量来表征(比如:128维的SIFT特征)。因此,为了可以让Kd-tree满足对高维数据的索引,Jeffrey S. Beis和David G. Lowe提出了一种改进算法——Kd-tree with BBF(Best Bin First),该算法可以实现近似K近邻的高速搜索。

在介绍BBF算法前。我们先来看一下原始Kd-tree是为什么在低维空间中有效而到了高维空间后查找效率就会下降。在原始kd-tree的近期邻查找算法中(第一节中介绍的算法)。为了可以找到查询点Q在数据集合中的近期邻点,有一个重要的操作步骤:回溯,该步骤是在未被訪问过的且与Q的超球面相交的子树分支中查找可能存在的近期邻点。

随着维度K的增大。与Q的超球面相交的超矩形(子树分支所在的区域)就会添加,这就意味着须要回溯推断的树分支就会很多其它,从而算法的查找效率便会下降非常大。

一个非常自然的思路是:既然kd-tree算法在高维空间中是因为过多的回溯次数导致算法查找效率下降的话。我们就能够限制查找时进行回溯的次数上限,从而避免查找效率下降。

这样做有两个问题须要解决:1)最大回溯次数怎么确定?2)如何保证在最大回溯次数内找到的近期邻比較接近真实近期邻。即查找精确度不能下降太大。

保证一定查找精度的前提下使得查找速度较快

问题1):最大回溯次数怎么确定?

最大回溯次数一般人为设定,通常依据在数据集上的实验结果进行调整。

问题2):如何保证在最大回溯次数内找到的近期邻比較接近真实近期邻。即查找精确度不能下降太大?

限制回溯次数后。假设我们还是依照原来的回溯方法挨个地进行訪问的话。那非常显然最后的查找结果的精度就非常大程度上取决于数据的分布和回溯次数了。挨个訪问的方法的问题在于觉得每一个待回溯的树分支中存在近期邻的概率是一样的,所以它对全部的待回溯树分支一视同仁。实际上。在这些待回溯树分支中,有些树分支存在近期邻的可能性比其它树分支要高,由于树分支离Q点之间的距离或相交程度是不一样的,离Q更近的树分支存在Q的近期邻的可能性更高。因此,我们须要差别对待每一个待回溯的树分支。即採用某种优先级顺序来訪问这些待回溯树分支。使得在有限的回溯次数中找到Q的近期邻的可能性非常高。

我们要介绍的BBF算法正是基于这种解决思路。以下我们介绍BBF查找算法。

基于BBF的Kd-Tree近似近期邻查找算法

已知:

Q:查询数据;   KT:已建好的Kd-Tree;

1. 查找Q的当前近期邻点P

1)从KT的根结点開始,将Q与中间结点node(k,m)进行比較,依据比較结果选择某个树分支Branch(或称为Bin);并将未被选择的还有一个树分支(Unexplored Branch)所在的树中位置和它跟Q之间的距离一起保存到一个优先级队列中Queue;

2)依照步骤1)的过程。对树分支Branch进行如上比較和选择,直至訪问到叶子结点。然后计算Q与叶子结点中保存的数据之间的距离,并记录下最小距离D以及相应的数据P。

 

注:

A、Q与中间结点node(k,m)的比較过程:假设Q(k) > m则选择右子树,否则选择左子树。

 

B、优先级队列:依照距离从小到大的顺序排列。

C、叶子结点:每一个叶子结点中保存的数据的个数可能是一个或多个。

 

2. 基于BBF的回溯

已知:最大回溯次数BTmax

1)假设当前回溯的次数小于BTmax,且Queue不为空。则进行例如以下操作:

从Queue中取出最小距离相应的Branch,然后依照1.1步骤訪问该Branch直至达到叶子结点;计算Q与叶子结点中各个数据间距离,假设有比D更小的值,则将该值赋给D。该数据则被觉得是Q的当前近似近期邻点。

2)反复1)步骤,直到回溯次数大于BTmax或Queue为空时,查找结束,此时得到的数据P和距离D就是Q的近似近期邻点和它们之间的距离。

 

以下用一个简单的样例来演示基于Kd-Tree+BBF的近似近期邻查找的过程。

数据点集合:(2,3), (4,7), (5,4), (9,6), (8,1), (7,2) 。

基于BBF的查找的过程:

查询点Q:   (5.5, 5)

amcl 之kd_tree改进算法_第1张图片amcl 之kd_tree改进算法_第2张图片

第一遍查询

从根结点(7,2)开始,5.5<7,进入右子树,(9,6),因为5<6,进入左子树节点(8,1)

你可能感兴趣的:(amcl 之kd_tree改进算法)