简体   繁体   English

查找网格上2个点之间的距离

[英]Find distance between 2 points on grid

Im finding the distance between two points, given departure = [x,y] and destination = [x,y] . 我在给定departure = [x,y]destination = [x,y]找到了两点之间的距离。 With x or y, one is always a float and the other an int, so its always on a line. 使用x或y时,一个始终为浮点数,另一个为int,因此其始终在一行上。 You have to stay on the gridlines to get to the destination point, and there is no set incrementation. 您必须停留在网格线上才能到达目的地,并且没有设置增量。 I havent seen any other posts on finding distance on a grid that deal with the mix of ints and floats so here I am. 我还没有看到其他有关在网格上查找距离以处理整数和浮点数的文章,所以我在这里。

This is my code: 这是我的代码:

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

An example would be departure = [0.4, 1] and destination = [0.9, 3] , it should equal 2.7, but I get 2.5 例如, departure = [0.4, 1]destination = [0.9, 3] ,它应该等于2.7,但我得到2.5

For example, you go from [0.4, 1] to [1, 1] to [1, 3] to [0.9, 3] for a total difference of 2.7. 例如,您从[0.4, 1][1, 1]再到[1, 3]再到[0.9, 3] ,总差为2.7。 It's like calculating the Manhattan distance, but instead of starting and ending at lattice points, you might start and/or end half-way down a block. 这就像计算曼哈顿距离,但不是在格点处开始和结束,而是可以在一个街区的一半处开始和/或结束。

When you look at the different combinations, it seems like the naive Manhattan distance will work, except when your path takes on a "C" shape (as given in the example). 当您查看不同的组合时,似乎天真的曼哈顿距离将起作用, 除非您的路径采用“ C”形(如示例中所示)。 This will happen if and only if your two float points are both x-coordinates or y-coordinates and have the same integer part. 仅当您的两个浮点都是x坐标或y坐标具有相同的整数部分时,才会发生这种情况。

An attempt might look like: 尝试可能看起来像:

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

From each house take a short-range taxicab to a corner. 从每所房子乘一个短程出租车到一个角落。 You have two ways of doing so. 您有两种方法可以这样做。 Then -- take a long-range taxicab between the resulting corners. 然后-在出现的角落之间走远距离的出租车。 There are 2x2 = 4 possibilities, depending on the corners traveled to. 有2x2 = 4种可能性,具体取决于行驶的弯道。 Take the min: 以分钟:

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))

For example, 例如,

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

It's not the mix of int and float , probably you are experiencing floating point error. 它不是intfloat的混合,可能是您遇到浮点错误。 floats are not exact, they are approximate, and can therefore be "off" by small amounts. floats不是精确的,它们是近似值,因此可以少量“偏离”。

You could use Decimal objects provided by the decimal module to work accurately with floating point values. 你可以使用Decimal通过所提供的对象decimal模块与浮点值准确工作。 Here's an example: 这是一个例子:

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

The final result will still be "off", but using Decimal will help to avoid cumulative rounding errors: 最终结果仍将为“ off”,但是使用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')

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

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