找到网格上2点之间的距离

时间:2016-04-13 00:33:41

标签: python algorithm distance

我找到两个点之间的距离,给定departure = [x,y]destination = [x,y]。对于x或y,一个总是浮点数,另一个是整数,所以它总是在一条线上。您必须保持在网格线上才能到达目标点,并且没有设置增量。我没有看到任何其他关于在网格上找到距离来处理整合和浮动的帖子,所以我在这里。

这是我的代码:

def perfectCity(departure, destination):
    return abs(destination[0]-departure[0]) + abs(destination[1]-departure[1]) 

一个例子是departure = [0.4, 1]destination = [0.9, 3],它应该等于2.7,但我得到2.5

例如,您从[0.4, 1][1, 1][1, 3]再到[0.9, 3],总差异为2.7。这就像计算曼哈顿距离,但不是在格点处开始和结束,而是可以在一个块的中途开始和/或结束。

3 个答案:

答案 0 :(得分:2)

当您查看不同的组合时,似乎天真的曼哈顿距离将起作用,除了,当您的路径采用“C”形状时(如示例中所示)。当且仅当您的两个浮点数都是x坐标或y坐标具有相同的整数部分时,才会发生这种情况。

尝试可能如下:

def minimum_distance(p1, p2):

    i1, i2 = int(p1[0]), int(p2[0])

    # if both x-coordinates are floats and they have the same integer part
    if i1 != p1[0] and i2 != p2[0] and i1 == i2:

        # find the decimal parts
        d1, d2 = p1[0] - i1, p2[0] - i2

        # find the smaller "C"
        x = min(d1 + d2, (1-d1) + (1-d2))

        # add the y distance to the "C" distance
        return abs(p1[1] - p2[1]) + x

    # repeat with the "y-coordinates are floats" case
    i1, i2 = int(p1[1]), int(p2[1])
    if i1 != p1[1] and i2 != p2[1] and i1 == i2:
        d1, d2 = p1[1] - i1, p2[1] - i2
        y = min(d1 + d2, (1-d1) + (1-d2))
        return abs(p1[0] - p2[0]) + y

    # simple case, return the Manhattan distance
    return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1])


print(minimum_distance([0.4, 1], [0.9, 3]))
# 2.7

答案 1 :(得分:2)

从每个房子乘坐短程出租车到一个角落。你有两种方法可以做到这一点。然后 - 在产生的角落之间进行远程出租车。根据行进的角落,有2x2 = 4种可能性。拿最小值:

from math import ceil,floor

#as a helper function, vanilla taxicab:

def t(p,q):
    x,y = p
    z,w = q
    return abs(x-z)+abs(y-w)

#find the two corners closest to a point:

def corners(p):
    x,y = p
    if isinstance(x,float):
        return [(floor(x),y),(ceil(x),y)]
    else:
        return [(x,floor(y)), (x,ceil(y))]

#combine these:   

def dist(p,q):
    return min(t(p,c) + t(c,d) + t(d,q)  for c in corners(p) for d in corners(q))

例如,

>>> dist((.4,1),(.9,3))
2.7

答案 2 :(得分:0)

这不是intfloat的混合,可能是您遇到了浮点错误。 floats并不准确,它们是近似的,因此可以少量“关闭”。

您可以使用decimal模块提供的Decimal个对象来准确处理浮点值。这是一个例子:

>>> 1.1 + 2.2        # will produce small error
3.3000000000000003
>>> from decimal import Decimal
>>> Decimal('1.1') + Decimal('2.2')
Decimal('3.3')

最终结果仍然是“关闭”,但使用Decimal将有助于避免累积舍入错误:

>>> 3.3 - (1.1 + 2.2)
-4.440892098500626e-16
>>> Decimal(3.3) - (Decimal(1.1) + Decimal(2.2))
Decimal('-4.440892098500250464677810669E-16')
>>> Decimal('3.3') - (Decimal('1.1') + Decimal('2.2'))
Decimal('0.0')