ikdtree解析

ikdtree

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)=2T(N/2)+O(N)=2(2T(N/4)+O(N/2))+O(N)=4T(N/4)+O(2N)
. . . = N ∗ T ( 1 ) + O ( ( K − 1 ) N ) ...=N*T(1)+O((K-1)N) ...=NT(1)+O((K1)N)
其中 T ( 1 ) = 0 T(1)=0 T(1)=0,因为最后一个点时会直接退出。
K为二叉树的层数, K − 1 = l o g ( N ) K-1=log(N) K1=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, 待续…

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值