使用曼哈顿距离无法找到最有效的元素

时间:2018-10-27 11:43:53

标签: python coordinates distance

我有一个带有障碍物的迷宫,它在地图上有不同的“能量提升”。它们只是最终需要达到的目标目的地。但是,到达它们的顺序很重要,因为我们希望节省时间。

让我们模拟以下情况:

   0  1  2  3
0 [ ][X][ ][ ]
1 [ ][▣][▣][ ]
2 [ ][P][ ][ ]
3 [ ][▣][Y][▣]
4 [ ][▣][ ][ ]

[▣] is an obstacle.
[X] with position (0,1) is a power-up
[Y] with position (3,2) is a power-up
[P] with position (2,1) is the player. In other words, the starting position

[P]需要通电。

为了确定当前哪个项目,我使用曼哈顿距离来找到最接近的项目:

abs(a1[0] - a2[0]) + abs(a1[1] - a2[1])

曼哈顿距离将计算[P][X]之间的距离为2,而[P][Y]之间的距离也为2。因此它将随机选择一个接下来访问。

但是,曼哈顿距离不会考虑[P][X]之间存在障碍,因此实际距离会更长。

因此,需要四个步骤才能到达[X]

(2,1) first step-> (2,0) second step-> (1,0) third-> (0,0) fourth-> (0,1) 

到达[Y]时,只需执行2个步骤:

(2,1) first step-> (2,2) second step-> (3,2)

由于曼哈顿距离在某些情况下会为我完成工作,因此它不是最省时的方法。另外,时间对我来说很关键,因为我想在最短的时间内获得所有力量,从而赢得比赛。

有人可以建议我如何优化这一点,或者在考虑到我所遇到的障碍的情况下使用哪种其他方法来计算最接近的项目?

1 个答案:

答案 0 :(得分:0)

为了知道哪个加电实际上是最接近的,您需要为每次加电计算实际距离(考虑到障碍物)。有了这些距离后,您可以比较它们,看看哪个实际上是最接近的。 但是,这似乎并不是解决您问题的最佳解决方案,因为您必须进行所有计算才能采取行动。

您现在正在做的事情很好,但是我们有一种方法可以改善它。您可以使用这种方法来确定曼哈顿的距离和障碍物的数量:

def manhattan_d_obstacles(grid, x1, y1, x2, y2):
    obs_count = 0
    if x1 > x2:
        x_range = range(x2, x1)
    else:
        x_range = range(x1, x2)
    if y1 > y2:
        y_range = range(y1, y2)
    else:
        y_range = range(y2, y1)
    for i in x_range:
        for j in y_range:
            if grid[i, j] == 'obstacle':
                obs_counter += 1
    return {
        "dist": abs(x1 - x2) + abs(y1 - y2),
        "obs": obs_counter
    }

现在,您只需使用此方法即可比较曼哈顿距离和该路径上的障碍物数量。所以:

best = {
    "dist": float("inf"), # int("inf") does not exist
    "obs": float("inf") # int("inf") does not exist
}
for pwu in power_ups:
    path = manhattan_d_obstacles(P['x'], P['y'], pwu['x'], pwu['y'])
    if path['dist'] < best['dist']:
        best = path
    elif path['dist'] == best['dist'] and path['obs'] < best['obs']:
        best = path

在实际路线不同于曼哈顿路线(即您的示例中P-> Y是)的情况下,此函数通常比计算实际距离运行得更快。否则,它将以相同的速度运行。