为什么有人会在KD树上使用八叉树?


32

我在科学计算方面有一些经验,并且在BSP(二进制空间分区)应用程序中广泛使用了kd树。最近,我对八叉树越来越熟悉,八叉树是一种类似的数据结构,用于对3-D欧几里得空间进行分区,但是从我收集到的数据中,它以固定的固定间隔工作。

一点独立性研究似乎表明,对于大多数数据集,kd树通常在性能上都更好-构造和查询更快。我的问题是,八叉树在空间/时间性能或其他方面的优势是什么?在什么情况下它们最适用(我听说过3D图形编程)?我将不胜感激地总结两种类型的优点和问题。

另外,如果有人能详细说明R树数据结构的用法及其优势,我也将不胜感激。R树(比八叉树更是如此)似乎与kd树非常相似地应用于k最近邻或范围搜索。


我应该注意,kd树和R树(但不是八叉树)似乎都是专门为促进k最近邻居搜索而设计的-在这种意义上它们如何比较?
Noldorin

需要注意的是,kd树的深度很小。压缩的四叉树可以帮助您到达那里,但使用起来却不太方便。
Suresh Venkat

@Suresh Venkat:谢谢。我对压缩四叉树不熟悉,但是它们真的适合3D空间代表吗?也许有一个“压缩八叉树”类似物。
Noldorin

我还听说,当八叉树具有已知的Z阶(空间填充)曲线时,更合适,但此处的推论不确定。
Noldorin

Answers:


23

k D中的细胞ķd树中可以具有高的纵横比,而八叉树单元格可以保证是立方的。由于这是一个理论板,因此我将为您提供高纵横比是个问题的理论原因:它使得无法使用体积边界来控制在解决近似最近邻查询时必须检查的像元数。

更详细地讲:如果您要向查询点q近似最近邻,而实际最近邻在距离d处,则通常以搜索来检查从内部到目标的每个数据结构单元的结尾。环形或环形壳的外部,其内部半径为d,外部半径为1 +ϵqdd。如果细胞具有有界的纵横比,因为它们是在四叉树,然后可以有至多 1 / ε d - 1层这样的细胞,并且可以在时间为查询证明良好界限。如果长宽比不受限制,例如(1+ϵ)d1/ϵd1树,这些界限不适用。kD

树与四叉树相比具有不同的优势,因为它们保证具有最大对数深度,这也有助于最近邻居查询的时间。但是,四叉树的深度最多为输入精度的位数,通常不大,并且有一些理论方法可将深度控制为基本对数(请参见跳过四叉树数据结构)。kd


4
有关压缩四叉树的最新摘要,请参见Sariel Har-Peled的最新教科书。
Jeffε

大卫,谢谢你的定量总结。只需确认一下:您使用的“长宽比”是否与“分支比例”同义?我一定要检查跳过四叉树/八叉树,也许还要压缩四叉树/八叉树。
Noldorin 2012年

1
矩形框的长宽比可以定义为其最长边缘长度与最短边缘长度之比。在这种情况下,我不知道什么是分支比,但是纵横比与树的分支因子无关(这对两个数据结构都是恒定的)。
大卫·埃普斯坦

我错过了“牢房”。现在有意义。
Noldorin 2012年

15

我和一群朋友正在做一个RTS太空游戏,这是一个有趣的附带项目。我们正在使用在计算机科学学院获得的很多知识来提高其效率,从而使我们能够在以后组建庞大的军队。

为此,我们考虑使用kd-tree,但我们很快就将其消除了:插入和删除在我们的程序中极为普遍(请考虑一艘飞过太空的飞船),这与kd-tree实在是一团糟。因此,我们为游戏选择了八叉树。


嗯,是的,我之前也听说过。使用kd-tree进行插入/删除是一项昂贵的操作(由于重新平衡)。我相信最佳情况下的时间复杂度仍然相同...
Noldorin

2
这取决于您如何修复kd-tree。最好的最佳情况下的时间复杂度不是我通常想要的目标:例如bogosort具有O(1)最佳情况下的复杂度,但我希望没有人使用它。
亚历克斯(Alex)10 Brink

不幸的是,对于这些数据结构上的常见操作,我似乎找不到任何复杂的时间复杂性摘要,但我并不介意。平均情况下的时间复杂度通常很有见地...
Noldorin

1
我真的认为,如果仅使用循环轴并仅将空间划分为中间的KD树,您仍然会做得更好。跳过笨重的SAH和其他昂贵的中位数削减,您将得到的东西不仅比八叉树搜索得更快,而且构建起来也更快。由于您要像使用八叉树一样均匀地划分空间,而是使用二叉树而不是8叉树,因此之前进行删除的操作对于KD-tree来说应该不会更加复杂。将以类似的方式均匀分布。例如:你可以简单地删除空节点超越N的深度
龙能源

8

八叉树在空间/时间性能或其他方面的优势是什么?在什么情况下它们最适用(我听说过3D图形编程)?

kD树是平衡二叉树,八叉树是 尝试因此优缺点可能是从那些更一般的数据结构继承而来的。特别:

  • 重新平衡可能会很昂贵(八木不需要重新平衡)。
  • 平衡可以更好地处理异构性,因为它具有自适应性。
  • 八叉树中较高的分支因子意味着较浅的树(较少的定向和分配)用于均匀分布。

同样,二分法(如八叉树)在比特旋转方面很容易实现。同样,我认为八叉树在进行范围查找时可以从预先计算的距离中受益匪浅。

编辑

显然,我对尝试和同质性的引用需要澄清。

Tries是由字典树表示的数据结构族,并且用作序列键(最著名的是字符串,但也包含DNA序列以及哈希尝试的哈希值中的位)的字典。如果每个字典映射x,y和z坐标中的每个坐标的一个位(在trie的第一级中的最高有效位,在第二级的下一个有效位等),则trie是均匀地细分3D空间的八叉树。因此,八叉树继承了尝试的特征,通常是:

  • 高分支因子可能意味着浅树,几乎不会产生间接指示,因此搜索速度很快,例如,可以将20个级别的二叉树存储在4个级别的树中,分支因子为256。
  • 在插入和删除过程中,尝试不会重新平衡,从而节省了平衡二叉树所需的昂贵操作。

缺点是异构性可能导致尝试/八叉树失衡,因此搜索可能需要许多间接操作。尝试中的等效问题通过使用边缘压缩将多个间接级别折叠为单个级别来解决。Octree不会这样做,但是没有什么可以阻止您压缩八叉树(但是我不认为您可以将结果称为八叉树!)。

为了进行比较,请考虑使用专门的字典作为字典字符串字典,将其表示为trie。特里的第一层分支在键的第一个字符上。第二级上第二个字​​符,依此类推。通过从字典中的键中搜索第一个字符以获取第二个词典来查找任何字符串,该第二个词典用于从键中查找第二个字符,依此类推。一组随机密钥字符串将是同质分布。一组都共享一些前缀的键字符串(例如,所有以“ anti”开头的单词)是异类的分配。在后一种情况下,第一个字典仅包含一个绑定,用于“ a”,第二个仅包含一个绑定,用于“ n”,依此类推。在特里树中搜索任何映射始终是通过使用相同的四个键来搜索相同的四个字典。这是低效的,这就是八叉树的作用,例如,如果八叉树用于存储异质粒子分布,其中绝大多数粒子位于矢量空间内的一小部分中,该八叉树就是这样。


“尝试就是尝试”?另外,“更好地处理异质性”是什么意思?关于树木,同质不是一个词。
Noldorin 2012年

2
“八角树不需要重新平衡”?对于存储异构点分布的八叉树,绝对不是这样。或者,取决于您对“八叉树”的一般定义:无论如何,重新平衡八叉树是根本不可能的
Jeffε

@Noldorin“尝试尝试八叉树”。是。你知道特里是什么吗?en.wikipedia.org/wiki/Trie
乔恩·哈罗普

@Noldorin“关于树木,我不是遇到同质词”。我指的是正在分配的分布的同质性。例如,当在3D空间中分配粒子时,固体中的原子会均匀分布,而宇宙中的恒星则是异质分布。kD树更适合于异构分布,因为它们的空间细分是自适应的。
乔恩·哈罗普

@Jɛff E“重新平衡八叉树根本是不可能的”。这正是我所指的。抱歉,如果我的措辞令人困惑。
乔恩·哈罗普

2

八进制可用作连续体模型的基础数据类型,请参见例如Gerris流求解器。在流体动力学中,生活已经足够困难,因此,要知道所有子立方体的大小仅取决于其深度,就必须简化这一因素。

警告:我不是流体动力学家!


有趣。我绝对可以欣赏到在连续模型中使用八叉树更容易...我想知道为什么图形编程是什么原因?
Noldorin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.