【发布时间】:2018-06-21 00:18:52
【问题描述】:
我正在寻找一些用于范围搜索的数据结构。我认为范围树提供了很好的时间复杂度(但有一些存储要求)。
但是,在我看来,其他数据结构,如 KD-trees,比 范围树 更受讨论和推荐。这是真的?如果有,为什么?
【问题讨论】:
标签: data-structures computational-geometry kdtree range-tree
我正在寻找一些用于范围搜索的数据结构。我认为范围树提供了很好的时间复杂度(但有一些存储要求)。
但是,在我看来,其他数据结构,如 KD-trees,比 范围树 更受讨论和推荐。这是真的?如果有,为什么?
【问题讨论】:
标签: data-structures computational-geometry kdtree range-tree
我希望这是因为 kd-trees 可以直接扩展到包含点以外的对象。这给了它许多应用,例如虚拟世界,我们想要快速查询三角形。范围树的类似扩展并不简单,事实上我从未见过。
简单回顾一下:kd-tree 可以在 O(n log n) 时间内将 d 空间中的一组 n 点预处理为使用 O(n) 空间的结构,这样任何 d 维范围查询可以在 O(n1-1/d + k) 时间内回答,其中 k 是回答的数量。范围树需要 O(n logd-1n) 时间进行预处理,占用 O(n logd-1n) 空间,并且可以在 O 中回答范围查询(logd-1n + k) 时间。
如果我们谈论的是 2 维或 3 维空间,范围树的查询时间显然比 kd 树的查询时间要好得多。然而,kd-tree 有几个优点。首先,它总是只需要线性存储。其次,它总是在 O(n log n) 时间内构建。第三,如果维度非常高,它将优于范围树,除非您的点集非常大(尽管可以说,此时线性搜索几乎与 kd-tree 一样快)。
我认为另一个重要的一点是,kd-trees 比范围树更广为人知。在参加计算几何课程之前,我从未听说过范围树,但我之前听说过并使用过 kd-trees(尽管是在计算机图形设置中)。
编辑:当您拥有数百万个点时,您会问什么是 2D 或 3D 固定半径搜索更好的数据结构。我真的不能告诉你!我倾向于说,如果您执行许多查询,范围树会更快,但对于 3D,构建速度会慢 O(log n) 倍,并且内存使用可能会在速度之前成为问题。我建议集成这两种结构的良好实现,并简单地测试什么能更好地满足您的特定需求。
【讨论】:
为了满足您的需求(2D 或 3D 粒子模拟),您需要一个能够进行所有最近邻查询的数据结构。覆盖树是最适合此任务的数据结构。我在计算最近邻以进行核密度估计时遇到了它。这个Wikipedia page 解释了树的基本定义,John Langford's page 有一个 C++ 实现的链接。
单个查询的运行时间为O(c^12*logn),其中c是数据集的扩展常数。这是一个上限——实际上,数据结构的执行速度比其他数据结构快。 This paper 表明,粒子模拟所需的所有最近邻居(对于所有数据点)的批处理运行时间为 O(c^16*n),并且这个理论线性界限对您也很实用需要。构建时间为 O(nlogn),存储时间为 O(n)。
【讨论】: