繁体   English   中英

用更少的比较来比较两个元组列表的欧几里得距离

[英]Compare the Euclidean distance of two lists of tuples with fewer comparisons python

我正在尝试计算阈值为4的两个元组列表的欧几里得距离。 如果阈值小于特定值,则增加计数器。 每个元组是该点的x,y,z坐标。 无论如何,我可以降低list1与list2的比较。

  X = [ (1,2,3),(2,3,4), (4,5,6) ]
  Y = [ (1,2,2) , (3,4,5),(6,7,8) ]
  from math import sqrt
  dist_X = [ sqrt((p[0] - 0)**2 + (p[1] - 0)**2 + (p[2] - 0)**2) for p in X]
  dist_Y = [ sqrt((p[0] - 0)**2 + (p[1] - 0)**2 + (p[2] - 0)**2) for p in Y]
  for x in dist_X:
     print (x ,  [ i for i,y in enumerate(dist_Y) if abs(x-y) <= 4])

我正在考虑先计算具有原点(0,0,0)的每个点的欧几里得距离,以便现在两个列表都包含彼此靠近的点,但是由于其标量值而无法工作。朝着正确的方向前进?

编辑

   visited1 = [ (1,2,3),(2,3,4), (4,5,6) ]
   visited2   = [ (1,2,2) , (3,4,5),(6,7,8) ]
    def euclidean(a,b):
        return sqrt((a[0] - b[0])**2+(a[1]-b[1])**2+(a[2]-b[2])**2)
   comparison = 0
   for i,j in enumerate(visited2):
     for k,l in enumerate(visited1):
         if euclidean(visited2[i],visited1[k]) < 4:
                 count += 1
         comparison += 1

在这种情况下,将list1的每个元素与list2的每个元素进行比较..我想知道是否有一种方法可以在给定我拥有points(x,y,z)的情况下最小化比较?

一种有时会加快速度的预计算是kd树 我针对蛮力进行了快速测试,发现对于较大的列表,它们可以更快一些:

# n = 10
# trees                 0.08512560 ms
# brute                 0.01425540 ms
# n = 100
# trees                 0.20338160 ms
# brute                 0.09876890 ms
# n = 1000
# trees                 6.40193820 ms
# brute                16.15429670 ms
# n = 10000
# trees               298.69653380 ms
# brute              1393.71134270 ms

码:

import numpy as np
from scipy.spatial import cKDTree

import types
from timeit import timeit

def setup_data(n, k):
    data = {'d1': np.random.randint(0, 10, (n, 3)),
            'd2': np.random.randint(0, 10, (n, 3)),
            'mx': k}
    return data

def f_trees(d1, d2, mx):
    t1 = cKDTree(d1)
    t2 = cKDTree(d2)
    return t1.count_neighbors(t2, mx)

def f_brute(d1, d2, mx):
    dist2 = np.add.outer(np.einsum('ij,ij->i', d1, d1), np.einsum('ij,ij->i', d2, d2)) - 2*np.einsum('ij, kj', d1, d2)
    return np.count_nonzero(dist2 <= mx*mx)



for n in (10, 100, 1000, 10000):
    data = setup_data(n, 4)
    ref = np.array(f_trees(**data))
    print(f'n = {n}')
    for name, func in list(globals().items()):
        if not name.startswith('f_') or not isinstance(func, types.FunctionType):
            continue
        try:
            assert np.allclose(ref, func(**data))
            print("{:16s}{:16.8f} ms".format(name[2:], timeit(
                'f(**data)', globals={'f':func, 'data':data}, number=10)*100))
        except:
            print("{:16s} apparently failed".format(name[2:]))

以2D方式绘制此图形以查看其外观。 这点大概是从原点相同的距离不一定接近对方-你有三角不等式倒退,在那里。 例如,比较点(0,10),(0,11)和(-8,-6)。 它们都是从原点出发的10-11个单位,但最后一个距离其他两个地方不远。

如果要知道两个点是否彼此靠近,则需要计算这两个点之间的距离,而不是到任意第三点的距离。 问题的复杂度是二次方,不是线性的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM