在任意坐标周围找到半径为r的球体中的所有点

时间:2012-06-15 15:32:40

标签: algorithm

我正在寻找一种有效的算法,对于具有已知高度,宽度和长度的空间,给定固定半径R,以及在该空间中具有3维坐标的点列表N,将找到所有点在网格上任意点的固定半径R内。这个查询将使用不同的点进行多次,因此一个昂贵的预处理/排序步骤,以换取快速查询可能是值得的。这是我正在处理的应用程序的一个瓶颈步骤,所以任何时候我都可以切断它是有用的

到目前为止我尝试过的事情:

- 天真算法,迭代所有点并计算距离

- 将空间划分为具有长度为R的立方体的网格,并将点放入这些中。这样,对于每个点,我只需要查询直接相邻的桶。这有一个显着的加速

- 我尝试使用曼哈顿距离作为启发式算法。也就是说,在计算到任何点之间的距离之前,使用曼哈顿距离来过滤那些不可能在半径R内的距离(即曼哈顿距离<= sqrt(3)*的那些距离) R)。我认为这会提供加速,因为它只需要加法而不是乘法,但它实际上减慢了程序一点点

编辑:为了比较距离,我使用平方距离来消除必须使用sqrt函数。

显然,我可以加快速度,但我现在可以尝试使用任何建议。

并非它在算法级别上可能很重要,但我在C中工作。

6 个答案:

答案 0 :(得分:3)

将您的积分存储在具有三维空间的k-d tree中,您可以获得速度优势。这将使您在O(log n)摊销时间内进行搜索。

答案 1 :(得分:2)

不要在半径上进行比较,比较半径的平方。原因是,如果两点之间的距离小于R,则距离的平方小于R^2

这样,当你使用距离公式时,你不需要计算平方根,这是一个非常昂贵的操作。

答案 2 :(得分:1)

我建议使用K-D树或z曲线: http://en.wikipedia.org/wiki/Z-order_%28curve%29

答案 3 :(得分:1)

Binary Indexed Tree怎么样? (参考Topcoder教程)它可以扩展到n维度,并且编码更简单。

答案 4 :(得分:1)

Nicolas Brodu's NEIGHAND库完全符合您的要求,改进了bin-lattice算法。

更多细节可以在他的文章中找到:Query Sphere Indexing for Neighborhood Requests

答案 5 :(得分:0)

[我可能会误解这个问题。我发现难以解析问题陈述。]

在过去,设计这种类型的“早期出局”算法通常是好的,它们会进行测试以避免更昂贵的计算。在现代处理器中,分支预测的失败通常非常昂贵,并且那些早期测试实际上可能比完整计算更昂贵。 (唯一可以确定的方法是测量。)

在这种情况下,计算非常简单,因此可能最好避免构建数据结构或进行任何聪明的早期检查,而是尝试优化,向量化和并行化获得所需的吞吐量。

对于点P(x,y,z)和球体S(x_s,y_s,z_s,radius),成员资格测试是:

(x - x_s)^2 + (x - y_s)^2 + (z - z_s)^2 < radius^2

其中radius^2可以为查询中的所有点预先计算一次(避免任何平方根计算)。这些计算都是独立的,您可以并行计算几个点。像SSE这样的东西,你可能一次做四个。如果您有许多要测试的要点,您可以拆分列表并进一步并行化多个核心的工作。