less than 1 minute read

一、KD-Tree

1. 介绍

  • KD-Tree 是 k 维树的缩写;
  • 是在 k 维欧几里德空间上用来组织点的数据结构;
  • 是每个节点都为k维点的二叉树;所有非叶子节点可以看作是一个超平面,它把空间分割成两个半空间,该节点的选择与k维中垂直于超平面的那一维有关,其法线为该维度上的单位向量;
  • k-d 树是空间二分树(Binary space partitioning )的一种特殊情况;

2. 应用

k-d 树 可以使用在多种应用场合,如多维键值搜索(例:范围搜寻及最邻近搜索);

二、KD-Tree 运算

1. 创建

  • 在 K 维数据中选取一个维度 \(K_i\);
  • 在 \(K_i\) 维度上选取中值,并以此将数据划分为两个子集,此中值即为根节点;
  • 在两个子集上分别重复上述过程,所得数据作为上述节点的叶节点;

根据分割面选择策略的不同,有多种创建方法:
最典型的轮流法最大方差法

2. 删除

3. 修改

4. 平衡

5. 查找-最邻近搜索

找出在树中与输入点最接近的点:

从根节点按创建时的规则移动到叶节点;递归回来,此过程中,计算每个节点与输入的距离,并比较;

(1)从根节点开始,递归的往下移;往左还是往右的决定方法与插入元素的方法一样(如果输入点在分区面的左边则进入左子节点,在右边则进入右子节点);
(2)一旦移动到叶节点,将该节点当作「目前最佳点」;
(3)解开递归,并对每个经过的节点运行下列步骤:
  a. 如果目前所在点比目前最佳点更靠近输入点,则将其变为目前最佳点;
  b. 检查另一边子树有没有更近的点,如果有则从该节点往下找;
(4)当根节点搜索完毕后完成最邻近搜索;

三、实践

  1. OpenCV
    Bruteforce matcher:暴力法
    Flann-based matcher:快速近似最近邻检索

三、思考

  1. KD-Tree 相比循环,怎么节省了搜索时间
    why

四、扩展

  1. KDTree 中涉及回溯操作,所以对高维向量并不友好;通常维度超过 200 效率就不好,此时应该用 Ball Tree;
    why

TOP

附录

A. KD-Tree 的创建方法

轮流法

  • 选择轴/确定分割面:各维度轮流作为分割面的轴;
    以三维空间为例,若根节点是 x 轴垂直分割面,则其子节点皆为 y 轴垂直分割面,其孙节点皆为 z 轴垂直分割面,其曾孙节点则皆为 x 轴垂直分割面,依此类推;
  • 选择分割点:取该轴坐标的中位数; 此法会产生一个平衡的 k-d 树;然而,平衡的树不一定对每个应用都是最佳的;why-什么情况下不好

最大方差法

  • 选择轴/确定分割面:以方差最大的维度作为分割面的轴;
  • 选择分割点:取该轴坐标的中位数;

B. 资料

Comments