kdtree
先回顾一下kdtree的基本知识。
kdtree是可以存储K维数据的二叉树。
建树算法:
step1、初始化,确定根节点。
step2、
确定当前节点的分割轴
对所有点依据分割轴上的分量进行排序,找到中值。
中值两侧的点划分为新的左右子树node,并执行递归。
step4、node中包含的点的数量足够小,则停止。
分割轴可以按照维度顺序选取,如x-y-z。
建树时间复杂度:
O
(
n
l
o
g
(
n
)
∗
l
o
g
(
n
)
)
O(nlog(n)*log(n))
O(nlog(n)∗log(n)),
n
l
o
g
(
n
)
nlog(n)
nlog(n) 是排序的时间复杂度,
l
o
g
(
n
)
log(n)
log(n)是树的层数。
空间复杂度:
需要保存N个点,每个点k维度,所需空间kN, 每个node需要保存所属的全部点的index,树的任意一层所需空间N,一共
log(N)层,则总共的空间复杂度为
O
(
k
N
+
N
l
o
g
(
N
)
)
O(kN+Nlog(N))
O(kN+Nlog(N))
优化的trick:
1、排序改为找中值算法,如std::nth_element, 或者用平均值代替,此时建树复杂度为
O
(
N
l
o
g
(
N
)
)
O(Nlog(N))
O(Nlog(N))。
2、自适应分割轴选取 - 分割轴的选取采用协方差最大原则。
附KDTREE建树时间复杂度证明
T
(
N
)
=
2
∗
T
(
N
/
2
)
+
O
(
N
)
=
2
∗
(
2
∗
T
(
N
/
4
)
+
O
(
N
/
2
)
)
+
O
(
N
)
=
4
∗
T
(
N
/
4
)
+
O
(
2
∗
N
)
T(N)=2*T(N/2)+O(N)=2*(2*T(N/4)+O(N/2))+O(N)=4*T(N/4)+O(2*N)
T(N)=2∗T(N/2)+O(N)=2∗(2∗T(N/4)+O(N/2))+O(N)=4∗T(N/4)+O(2∗N)
.
.
.
=
N
∗
T
(
1
)
+
O
(
(
K
−
1
)
N
)
...=N*T(1)+O((K-1)N)
...=N∗T(1)+O((K−1)N)
其中
T
(
1
)
=
0
T(1)=0
T(1)=0,因为最后一个点时会直接退出。
K为二叉树的层数,
K
−
1
=
l
o
g
(
N
)
K-1=log(N)
K−1=log(N), 所以
T
(
N
)
=
O
(
N
l
o
g
(
N
)
)
T(N)=O(Nlog(N))
T(N)=O(Nlog(N))
ikdtree
与许多kdtree的实现不同,kdtree通常只在叶子节点保存point,而ikdtree会在叶子节点和内部节点都存储对应point,从而更好的支持动态点插入与re-balancing.
建树
构造ikdtree类似于构建普通的kdtree.
增量更新
ikdtree的增量更新是指先进行增量操作,再进行re-balancing的整个过程。支持点操作和盒操作,点操作是指操作单一一个点,而盒操作是指操作一个给定轴对齐盒子内的全部点。
常用ikdtree的更新方法是:基于点操作的插入新点,并通过盒操作的删除点。
点插入以及同时降采样
ikdtree支持同时插入点以及降采样,伪代码如下图所示:
解析:
输入:给定激光点p以及降采样voxel resolution l。
第二行:用降采样分辨率为l的cube对空间进行划分,并获取点p所属于cube
C
D
C_D
CD。
第三行:算法仅保留最靠近cube中心的point,因此求解
C
D
C_D
CD的中心坐标
p
c
e
n
t
e
r
p_{center}
pcenter。
第四行~第五行:在kdtree中搜索
C
D
C_D
CD包含的点,并将这些点与新点P一起保存在V中。如何搜索出体素内的点??需要看看源码
第六行:计算V中所有点到
C
D
C_D
CD中心的距离,并找到最近的那一个点
p
n
e
a
r
e
s
t
p_{nearest}
pnearest。
第七行:
C
D
C_D
CD的所有点被删除。
第八行:
p
n
e
a
r
e
s
t
p_{nearest}
pnearest插入到kdtree。
插入算法-Function Insert():
采用递归实现
第12~14行:从根节点向下搜索,直到找到一个空节点来追加一个新节点。
第15行:获取当前kdtree的分割轴序号ax。
第16~20行:将当前点p在轴上的分量与当前node的分量进行比较,
若<,则进入左子树递归搜索,否则进入右子树递归搜索。
第21行:更新树的属性(treesize、range)。
第22行:对新点加入后的子树进行平衡准则检查和维护,以保证ikdtree的平衡性。
下一节介绍 box-wise delete, 待续…