繁体   English   中英

列表中两点之间的距离公式

[英]Distance formula between two points in a list

我需要获取我创建的列表并找到最近的两个点并将它们打印出来。 我该如何去比较列表中的每个点?

没有任何需要绘制或任何东西,只需比较点并找到列表中最接近的两个点。

import math # 'math' needed for 'sqrt'

# Distance function
def distance(xi,xii,yi,yii):
    sq1 = (xi-xii)*(xi-xii)
    sq2 = (yi-yii)*(yi-yii)
    return math.sqrt(sq1 + sq2)

# Run through input and reorder in [(x, y), (x,y) ...] format
oInput = ["9.5 7.5", "10.2 19.1", "9.7 10.2"] # Original input list (entered by spacing the two points).
mInput = [] # Manipulated list
fList = [] # Final list
for o in oInput:
    mInput = o.split()
    x,y = float(mInput[0]), float(mInput[1])
    fList += [(x, y)] # outputs [(9.5, 7.5), (10.2, 19.1), (9.7, 10.2)]

重写您的distance()函数以将两个(x, y)元组作为参数会更方便:

def distance(p0, p1):
    return math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)

现在您想遍历列表fList所有点对。 函数iterools.combinations()为此目的很方便:

min_distance = distance(fList[0], fList[1])
for p0, p1 in itertools.combinations(fList, 2):
    min_distance = min(min_distance, distance(p0, p1))

另一种方法是定义distance()以接受单个参数中的点对

def distance(points):
    p0, p1 = points
    return math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)

并使用内置min()函数的key参数:

min_pair = min(itertools.combinations(fList, 2), key=distance)
min_distance = distance(min_pair)

我意识到这个问题有库限制,但为了完整性,如果你在 Nx2 numpy ndarray(2D 系统)中有N个点:

from scipy.spatial.distance import pdist
x = numpy.array([[9.5,7.5],[10.2,19.1],[9.7,10.2]])
mindist = numpy.min(pdist(x))

我总是鼓励人们使用 numpy/scipy,如果他们正在处理最好存储在数值数组中的数据,并且很高兴知道这些工具可供将来参考。

请注意, math.sqrt函数既慢又在这种情况下是不必要的。 尝试比较距离平方以加快速度(排序距离与距离平方将始终产生相同的排序):

def distSquared(p0, p1):
    return (p0[0] - p1[0])**2 + (p0[1] - p1[1])**2

您的固定代码。 没有有效的算法,只有蛮力算法。

import math # math needed for sqrt

# distance function
def dist(p1, p2):
    return math.sqrt((p2[0] - p1[0]) ** 2 + (p2[1] - p1[1]) ** 2)

# run through input and reorder in [(x, y), (x,y) ...] format
input = ["9.5 7.5", "10.2 19.1", "9.7 10.2"] # original input list (entered by spacing the two points)
points = [map(float, point.split()) for point in input] # final list

# http://en.wikipedia.org/wiki/Closest_pair_of_points
mindist = float("inf")
for p1, p2 in itertools.combinations(points, 2):
    if dist(p1, p2) < mindist:
        mindist = dist(p1, p2)
        closestpair = (p1, p2)

print(closestpair)

这可能有效:

oInput = ["9.5 7.5", "10.2 19.1", "9.7 10.2"]

# parse inputs
inp = [(float(j[0]), float(j[1])) for j in [i.split() for i in oInput]]

# initialize results with a really large value
min_distance = float('infinity')
min_pair = None

# loop over inputs
length = len(inp)
for i in xrange(length):
    for j in xrange(i+1, length):
        point1 = inp[i]
        point2 = inp[j]

        if math.hypot(point1[0] - point2[0], point1[1] - point2[0]) < min_distance:
            min_pair = [point1, point2]

循环完成后, min_pair 应该是距离最小的对。

使用 float() 解析文本留下了改进的空间。

math.hypot 比用手写的 Python 函数计算距离快三分之一

首先,一些注意事项:

a**2 # squares a
(xi - xii)**2 # squares the expression in parentheses.

mInput 不需要提前声明。
fList.append((x, y))比使用+=fList.append((x, y))

现在你有了fList 您的距离函数可以重写为采用 2 个 2 元组(点)参数,我不会在这里打扰。

然后你可以写:

shortest = float('inf')
for pair in itertools.combinations(fList, 2):
    shortest = min(shortest, distance(*pair))

上述许多问题建议使用math.sqrt ,这很慢,也不是求平方根的好方法。 尽管使用了这种方法,但只要回忆一下学校的基本概念:考虑取任何正数 x 的平方根。 然后平方根被写成二分之一的幂:x½。 因此,分数指数表示要取某个根。

所以而不是使用math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)

def distance(a,b):
  euclidean_distance = ((b[0]-a[0])**2 + (a[1]-a[1])**2)**0.5
  return(euclidean_distance)

希望能帮助到你

暂无
暂无

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

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