【问题标题】:Efficient way to find the shortest distance between two arrays?找到两个阵列之间最短距离的有效方法?
【发布时间】:2016-07-29 22:41:55
【问题描述】:

我试图找到两组数组之间的最短距离。 x- 数组是相同的,只包含整数。这是我正在尝试做的一个示例:

import numpy as np
x1 = x2 = np.linspace(-1000, 1000, 2001)
y1 = (lambda x, a, b: a*x + b)(x1, 2, 1)
y2 = (lambda x, a, b: a*(x-2)**2 + b)(x2, 2, 10)

def dis(x1, y1, x2, y2):
    return sqrt((y2-y1)**2+(x2-x1)**2)

min_distance = np.inf
for a, b in zip(x1, y1):
    for c, d in zip(x2, y2):
        if dis(a, b, c, d) < min_distance:
            min_distance = dis(a, b, c, d)

>>> min_distance
2.2360679774997898

此解决方案有效,但问题在于运行时。如果 x 的长度约为 10,000,则解决方案不可行,因为程序有 O(n^2) 运行时间。现在,我尝试做一些近似来加速程序:

for a, b in zip(x1, y1):
    cut = (x2 > a-20)*(x2 < a+20)
    for c, d in zip(x2, y2):
        if dis(a, b, c, d) < min_distance:
            min_distance = dis(a, b, c, d)

但该计划仍然需要比我想要的更长的时间。现在,据我了解,循环遍历 numpy 数组通常效率低下,所以我确信仍有改进的空间。关于如何加快这个程序的任何想法?

【问题讨论】:

标签: python arrays numpy runtime ipython


【解决方案1】:

您的问题也可以表示为二维碰撞检测,因此quadtree 可能会有所帮助。插入和查询都在 O(log n) 时间内运行,因此整个搜索将在 O(n log n) 时间内运行。

还有一个建议,由于 sqrt 是单调的,您可以比较距离的平方而不是距离本身,这样可以节省 n^2 平方根计算。

【讨论】:

    【解决方案2】:

    scipy 有一个 cdist function,它计算所有点对之间的距离:

    from scipy.spatial.distance import cdist
    import numpy as np
    
    x1 = x2 = np.linspace(-1000, 1000, 2001)
    y1 = (lambda x, a, b: a*x + b)(x1, 2, 1)
    y2 = (lambda x, a, b: a*(x-2)**2 + b)(x2, 2, 10)
    
    R1 = np.vstack((x1,y1)).T
    R2 = np.vstack((x2,y2)).T
    
    dists = cdist(R1,R2) # find all mutual distances
    
    print (dists.min())
    # output: 2.2360679774997898
    

    这比原来的 for 循环快 250 倍以上。

    【讨论】:

      【解决方案3】:

      这是一个难题,如果您愿意接受近似值,它可能会有所帮助。我会查看像 Spotify 的 annoy 这样的东西。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-17
        • 1970-01-01
        • 2015-08-28
        • 2010-09-10
        • 1970-01-01
        相关资源
        最近更新 更多