Search 用于三维半径搜索的kd树与八叉树

Search 用于三维半径搜索的kd树与八叉树,search,data-structures,kdtree,octree,Search,Data Structures,Kdtree,Octree,我试图找出哪种结构更适合做点的几个半径搜索,kd树还是八叉树?已经在中提到了,但没有回答。在我看来,由于八叉树的叶子大小固定,因此可以计算出我需要访问的分支,而对于kd树,您必须迭代访问分支,直到覆盖半径。对于3D和固定查询半径,八叉树是一个不错的选择。如果您需要在磁盘上工作,其他数据结构可能会更好,但是k-d树在这里也不起作用 为什么不两种方法都尝试一下,看看哪种方法更适合您的数据?在我的项目中,我使用八叉树进行范围搜索,它工作效率高,易于实现。但从未将其与KD Tree进行过比较。 据我所知

我试图找出哪种结构更适合做点的几个半径搜索,kd树还是八叉树?已经在中提到了,但没有回答。在我看来,由于八叉树的叶子大小固定,因此可以计算出我需要访问的分支,而对于kd树,您必须迭代访问分支,直到覆盖半径。

对于3D和固定查询半径,八叉树是一个不错的选择。如果您需要在磁盘上工作,其他数据结构可能会更好,但是k-d树在这里也不起作用


为什么不两种方法都尝试一下,看看哪种方法更适合您的数据?

在我的项目中,我使用八叉树进行范围搜索,它工作效率高,易于实现。但从未将其与KD Tree进行过比较。
据我所知,对于三维数据,kd树的最坏情况时间复杂度为O(n^(2/3)),而八叉树只能保证O(n)。所以,如果您关心最糟糕的时间复杂性,请选择KD树。(我不在乎最糟糕的时间复杂度,如果我在我的数据集中知道这永远不会发生。)

我已经亲自实现了,正是出于这个目的,我会投票支持八叉树。我发现使用八叉树更容易得到更有效的结果。我说得更容易,因为我认为有了这些微妙的区别,其实更多的是关于实现者,而不是数据结构。但我认为对大多数人来说,优化八叉树会更容易

其中一个原因是,K-D树本质上比二叉树更深,一次在一维上分裂。如果你想在叶子上寻找精确的匹配元素,比如光线/三角形的交叉点,在树下有一条清晰的路径,那么这种更深层次的特性会很有帮助。当一棵经过仔细拆分的深树符合搜索质量的概念时,它非常有用

如果你在最大半径范围内寻找最近的点,而你的大部分时间都是在树上走来走去,从叶子到父母到兄弟姐妹到祖父母到父母兄弟姐妹等等,那么仔细地分割一棵树并没有多大帮助。在这里,如果您可以以缓存友好的方式访问所有内容,并且可以轻松地使八叉树缓存友好,就像连续存储所有8个子缓存一样,这会有助于您实现更高的访问效率,此时您可以执行以下操作:

struct OctreeNode
{
    // Index of first child node. To get to the 4th node,
    // we just access nodes[first_child+3], e.g.
    int first_child;
    ...
};
所以无论如何,如果这是两个选择,我投票支持八叉树。同样对于这种类型的邻近搜索,您不一定希望八叉树太深。即使我们必须在较浅的树上寻找比最优点更多的点,这也比经常在树上上下爬要好。如果存储在叶中的点是连续的,则会有所帮助。在完成构建树之后,您可以通过后期处理潜在地实现这一点


请注意,对于这两种解决方案,您必须查看同级节点。离某个点最近的点不一定是位于同一叶节点中的点。在某些情况下,根据数据的性质,仅使用三维网格实际上可以达到最佳效果,因为使用三维网格时,您甚至不必费心从一个子网格到另一个子网格再到另一个子网格。3D网格在内存使用方面似乎具有爆炸性,但如果您将网格单元的内存开销降低到32位索引,则不必如此。在这种情况下,100x100x100网格占用的空间小于4 MB。

我希望这是一篇论文,这样我就可以引用你的话了。。。(在我的领域里)人们对这件事从来没有足够的烦恼过。谢谢你的解释,先生!