【问题标题】:Faster way to calculate distance between each point and remaining n-1 points计算每个点与剩余 n-1 个点之间距离的更快方法
【发布时间】:2018-12-13 18:43:04
【问题描述】:

我有 n 个点,我必须计算每个点与剩余 n-1 个点之间的欧几里得距离。我在python中使用了以下方法:

for eachRow in range(0, numberOfPoints):
        distanceProximityMatrix.append([])

    print('Initialisation Completed')
    for i in range(0, numberOfPoints):
        if(i%100 == 0) : print('.', end = '')
        for j in range(i, numberOfPoints):
            if(i != j):
                tempDist = distanceForMultivariate(recordsList[i], recordsList[j], attributesToBeUsed, isFirstColumnID = isFirstColumnID)
                distanceProximityMatrix[i].append(tempDist) 
                distanceProximityMatrix[j].append(tempDist)
            else :
                distanceProximityMatrix[i].append(0)

有没有更快的方法来做到这一点,因为我的积分数量很大,而且这个策略需要很长时间。

注意:distanceForMultivariate 函数计算欧式距离。

【问题讨论】:

  • 你对这些距离做了什么?也许您不需要所有这些?
  • @kutschkem 对于每个 i th 点,我想找到 k 个最近的点。

标签: python distance euclidean-distance


【解决方案1】:

我在这里假设二维点。那么欧式距离为:

sqrt( (x1 - x2)^2 + (y1 - y2)^2 )

我们这里有以下操作:

  • 2 减法
  • 2 次乘法
  • 1 次添加
  • 1 平方英尺

如果您只需要比较距离(例如,查找最近的邻居),您可以完全放弃 sqrt,因为它保留了顺序。不过要小心,不要让它们变得很大,如果你以后想对这些值求和,它们可能会变得很大。

三角方程不成立,所以不要在必要的地方使用它(所以没有寻路或基本上任何你可以求和距离的地方!):

if sqrt(a) + sqrt(b) >= sqrt(c), then
a + b <= a + 2sqrt(a*b) + b = (sqrt(a) + sqrt(b)) ^2 >= sqrt(c)^2 = c

sqrt(100) + sqrt(1) &gt;= sqrt(121)100 + 1 &lt; 121

话虽如此,如果您真的需要所有距离,我认为您无法降低复杂性,因为无论如何您都在计算 O(n^2) 值。

[由于应用程序现已清除而更新]

虽然我认为我的解决方案适用于查找最近的邻居,但实际上有更好的算法可以解决该问题,然后计算所有点对的一些距离。例如,kd-trees。

这个问题的答案可能会有所帮助:How to efficiently find k-nearest neighbours in high-dimensional data?

【讨论】:

    【解决方案2】:

    如果只是为了找到最近的k点,你觉得这个怎么样?
    首先将第一个 k 点放入某个排序数组(基于到源点的距离),然后计算最大距离,称为 d_max
    对于每个新点p,请进行以下检查:

    if (x_p - x_start > d_max) or (y_p - y_start > d_max)
    then disregard(x)
    else:
      d = distance (x, start);
      if d < d_max 
      then:
        insert_into_array(x) // obviously the array must stay sorted
        d_max = distance(array[k],start)
    

    背后的想法是:如果X坐标或Y坐标之间的差异大于最大距离,那么距离也会更大。

    例如
    想象一下你的起点是(2,2),你已经添加了(2,6)、(2,3)和(3,2),那么d_max就是4。 你的其他点是(10,0),(0,20)和(5,6),那么会发生以下情况:

    Add (10,0)? No, because 10 - 2 > 4 (x_p - x_start > d_max)
    Add (0,20)? No, because 20 - 2 > 4 (y_p - y_start > d_max)
    Add (5,6) ? Maybe: 5 - 2 <= d_max (X-coordinates) => ok
                       6 - 2 <= d_max (Y-coordinates) => ok
                       distance((5,6),(2,2)) = 5, which is larger than 4 => don't add (5,6)
    

    显然,您需要创建某种“数组”:

    • 您可以在其中添加一个点,在中间某处,以便其他点相应移动(链表)。
    • 如果您添加了一个点并且您已经有 k 条目,则应删除最后一个条目。

    因为你只需要比较距离,所以不需要计算平方根。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多