1. kd_tree
kd-tree(k-dimensional tree),一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。 主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索)。
2. kd_tree构建流程
2.1 流程图
2.2 示例
假设我们待划分的数据都是二维的:{(7,2),(5,4),(9,6),(2,3),(4,7),(8,1)}
-
首先,我们可以知道待划分的数据维度m=2;
-
确定划分维度,划分维度首先n=0,即先对每个(x,y)中的x做处理;
-
找划分维度的中位数M:先对所有数据排个序
(2,3), (4,7),(5,4),(7,2),(8,1),(9,6)
所以划分维度中位数M这里可以取(5,4)或(7,2)
这里选择(7,2),即其作为了树的根节点。其左边节点为(2,3),(4,7),(5,4);右边节点为(8,1),(9,6)
-
划分维度 = (当前划分维度+1)%数据维度,所以再次确定划分维度,即(0+1)%2=1,所以这次对(x,y)中的y做处理;
-
再次找划分维度的中位数M,对于(2,3),(4,7),(5,4)
再次排序(2,3),(5,4),(4,7),所以划分维度中位数M这里可以取(5,4);对于(8,1),(9,6),选择(9,6)作为右边的中位数M,即有
-
最终节点图
以上是对于二维数据的一个例子,其实就是每一层对每一维的点进行正确摆放。
在多维情况下,也同上,只是数据维数变多了而已
2. kd_tree搜索
2.1 步骤
2.2 示例
以上面那棵树为例,找离(6,5)最近的3个点
- 初始化最近距离表
KD_tree节点 | 距离 |
---|---|
node | inf |
node | inf |
node | inf |
- 回溯路径表
KD_tree节点 | 维度 | 比较[6,5] | 所属范围 |
---|---|---|---|
[7,2] | 0 | 6<7 | left |
[5,4] | 1 | 5>4 | right |
[4,7] | 0 | 6>4 | right |
- 计算最近距离
KD_tree节点 | 维度 | 比较[6,5] | 距离 |
---|---|---|---|
[7,2] | 0 | 6<7 | 3.16 |
[5,4] | 1 | 5>4 | 1.41 |
[4,7] | 0 | 6>4 | 2.83 |
KD_tree节点 | 距离 |
---|---|
[5,4] | 1.41 |
[4,7] | 2.83 |
[7,2] | 3.16 |
计算回溯路径表中的所有节点的距离(此处采用的是采用欧氏距离的计算方法),得到最新搜索半径3.16;
搜索半径:以目标点(6,5)为圆心,目标点到节点的距离;
- 划分维度距离
对于某一维度上,做差取绝对值
KD_tree节点 | 维度 | 比较[6,5] | 划分维度距离 |
---|---|---|---|
[7,2] | 0 | 6<7 | 7-6=1 |
[5,4] | 1 | 5>4 | 5-4=1 |
[4,7] | 0 | 6>4 | 6-4=2 |
将划分维度距离和搜索半径作比较,若划分维度距离小于搜索半径,要加入其对应左右子树
KD_tree节点 | 维度 | 比较[6,5] | 所属范围 | 距离 | 划分维度距离 | 划分维度距离<3.16 |
---|---|---|---|---|---|---|
[7,2] | 0 | 6<7 | left | 3.16 | 1 | right->[9,6] |
[4,7] | 0 | 6>4 | right | 2.83 | 2 | left->none |
[5,4] | 1 | 5>4 | right | 1.41 | 1 | left->[2,3] |
产生新的回溯路径表,再次计算距离,更新距离表,得到最新搜索半径
KD_tree节点 | 维度 | 比较[6,5] | 所属范围 | 距离 |
---|---|---|---|---|
[9,6] | 1 | 5<6 | left | 3.16 |
[2,3] | 0 | 6>2 | right | 4.47 |
KD_tree节点 | 距离 |
---|---|
[5,4] | 1.41 |
[4,7] | 2.83 |
[9,6] | 3.16 |
搜索半径最大3.16
KD_tree节点 | 维度 | 比较[6,5] | 所属范围 | 距离 | 划分维度距离 | 划分维度距离与3.16比较 |
---|---|---|---|---|---|---|
[9,6] | 1 | 5<6 | left | 3.16 | 1 | right->none |
[2,3] | 0 | 6>2 | right | 4.47 | 4 | 无需搜索 |
- 计算完成,没有产生新的回溯路径表,因此最近距离得到
KD_tree节点 | 距离 |
---|---|
[5,4] | 1.41 |
[4,7] | 2.83 |
[9,6] | 3.16 |