在空间中寻找比某个值更接近的点

时间:2013-03-20 03:15:45

标签: python performance algorithm numpy kdtree

在我正在开发的python应用程序中,我有一个3D点阵列(大小在2到100000之间),我必须找到彼此相距一定距离的点(比如在两个值之间,比如0.1)和0.2)。我需要这个用于图形应用程序,这个搜索应该非常快(10000点的样本约为1/10秒)

作为第一个实验,我尝试使用scipy.spatial.KDTree.query_pairs实现,并且使用5000点的样本,返回索引需要5秒。你知道任何可能适用于这种特殊情况的方法吗?

关于应用程序的更多信息:

点表示原子坐标,距离搜索对于确定原子之间的键很有用。债券不一定是固定的,但可能在每一步都发生变化,例如在氢键的情况下。

2 个答案:

答案 0 :(得分:4)

好问题!这是我的建议:

将每个坐标除以“epsilon”值0.1 / 0.2 / whatever,并将结果舍入为整数。这创建了点的“商空间”,其中不再需要使用距离公式确定距离,而是简单地通过比较每个点的整数坐标。如果所有坐标都相同,则原始点大约在彼此相差三倍的平方根内(例如)。这个过程是O(n),需要0.001秒或更短。

(注意:您可能希望使用此除法和舍入产生的三个附加整数来扩充原始点,这样您就不会丢失确切的坐标。)

使用字典样式规则按数字顺序对点进行排序,并将坐标中的三个整数视为单词中的字母。这个过程是O(n * log(n)),并且应该小于第二个要求的十分之一。

现在,您只需继续浏览此排序列表,并将每个点的整数坐标与前一个点和后一个点进行比较。如果所有坐标都匹配,则可以将两个匹配点移动到“保持”点列表中,并将所有其他点标记为“扔掉”。这是一个O(n)过程,只需要很少的时间。

结果将是所有原始点的子集,其中仅包含可能涉及任何键的那些点,键被定义为与原始集中的某个其他点大约相差或更小。< / p>

这个过程在数学上并不精确,但我认为它绝对快速且适合您的目的。

答案 1 :(得分:1)

我想到的第一件事是: 如果我们计算集合中每两个原子之间的距离,那么它将是O(N ^ 2)个运算。这很慢。 如何引入具有一些单元格大小的静态正交网格(例如接近您感兴趣的距离),然后确定属于网格的每个单元格的原子(它需要O(N)操作)在此过程之后,您可以减少搜索邻居的时间。