求3D点集中最近点的一个空间二叉树实现

                  求3D点集中最近点的一个空间二叉树实现
                   HouSisong@GMail.com  2010.09.12

 

(2011-03-04  修改节点内存泄漏,漏了一句m_nodePool.push_back(m_cur); )

 

tag:求3D点集中最近点,空间二叉树,点集最小包围球

摘要:
    这几天为了解决一个颜色空间匹配搜索速度太慢的问题(求3D点集中最近点),写了一个基于3D空间二叉树分割的算法的实现,

速度提高了几十倍;

正文:    

A: 问题简单描述
   已知3D点集U(较多),求出U中与给定点p最近的点;可能会非常多次 的给定不同的p点,而点集U不变;
 
B: 一些基础代码和最简单的一个实现和其简要优化
定义3D点:


寻找最近点的算法简单实现:

该算法遍历点集U(points[]),找寻点集中距离test_point最近的点,返回其坐标,算法复杂度为O(N);

简单优化:
前面的程序计算点之间的距离来比较大小,涉及到开方运算,比较慢;而比较的时候,改成比较距离的平方效果也一样,
函数返回距离的时候,在把最终结果开方就好了;代码如下:


这个代码的速度是前面实现的3倍多;
当然该算法还可以继续优化的;但因为算法复杂度太高,进一步优化的意义不大;
下面给出一个平均复杂度O(log(N))的算法

C: 基于3D空间二叉树分割的算法的实现
   对点集U进行预处理,生成一棵3D空间二叉树:
     将点集U的最长轴按中值划分成2个新的点集;计算新形成的2个点集的最小包围球;
     如果新划分出的点集的点个数比较多,可以进一步划分,一直到不用划分;
(划分方法可以是该轴的中值、均值或平分个数的值等,程序里选择用中值划分;
包围体也可以为其它3D几何包围体,比如正6面体等,程序里选择球型包围体,算法实现更简单快速些)

   利用二叉树寻找离给定点最近的点:
      程序用深度优先顺序遍历二叉树,遇到有2分支的时候优先处理距离近的分支;
      快速排除一个点集的算法原理: 假设搜寻过程中,当前已经得到的离p点最近的点的距离为minD,
现在寻找到了点集u(包围球半径ur,球心坐标up); 如果 (p到up的距离 - ur) > minD ,那么该点集u和
其子点集都可以立即排除掉了;而且该判断表达式还可以改进为 p到up的距离的平方>(minD+ur)的平方
计算起来就更加快速了;
     (如果想用广度优先算法遍历二叉树,可以维持一个队列,储存当前没有被排除的点集,然后展开这些点集,快速排除不可能的点集,直到没有点集分
支可以展开;这种遍历方式可以利用的快速排除一个点集的算法原理为: 假设搜寻过程中,当前已经得
到的离p点最近的点集距离为minD,该点集包围球半径为ur,现在寻找到了点集v(包围球半径vr,球心坐
标vp); 如果 (p到vp的距离 - mr) > (minD+ur),那么该点集v和其子点集就可以立即排除掉;该判断表
达式也可以改进为 p到vp的距离的平方 > (minR+ur+mr)的平方 !    )

代码实现:



D:完整测试代码



E:速度对比
   使用的编译器为vc2008;测试使用的CPU为i7 920;
--------------------------------------------
3D点集数量: 64
      遍历算法0: 每秒处理1134824个点
      遍历算法1: 每秒处理3564980个点
  空间2叉树算法: 每秒处理4871770个点
--------------------------------------------
3D点集数量: 256
      遍历算法0: 每秒处理291841个点
      遍历算法1: 每秒处理1059374个点
  空间2叉树算法: 每秒处理3144091个点
--------------------------------------------
3D点集数量: 1000
      遍历算法0: 每秒处理76064个点
      遍历算法1: 每秒处理295625个点
  空间2叉树算法: 每秒处理2068754个点
--------------------------------------------
3D点集数量: 10000
      遍历算法0: 每秒处理7643个点
      遍历算法1: 每秒处理30166个点
  空间2叉树算法: 每秒处理1111412个点
--------------------------------------------
3D点集数量: 100000
      遍历算法0: 每秒处理772个点
      遍历算法1: 每秒处理2984个点
  空间2叉树算法: 每秒处理604217个点
--------------------------------------------
3D点集数量: 1000000
      遍历算法0: 每秒处理83个点
      遍历算法1: 每秒处理272个点
  空间2叉树算法: 每秒处理272924个点

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值