【发布时间】:2021-04-16 10:55:57
【问题描述】:
我正在尝试用球找到迷宫的最短路径:球一直滚动直到撞到墙上。我使用 Dijkstra 的算法,使用heapq 作为优先级队列。但是,我得到了一条非最佳路径。
这是我的示例输入代码:
maze = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1],
[1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0],
[0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0],
[0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
start = (0, 0)
end = (22, 22)
def shortestDistance(maze: List[List[int]], start: List[int], destination: List[int]):
start, destination = tuple(start), tuple(destination)
row, col = len(maze), len(maze[0])
moves = [(-1, 0), (0, 1), (0, -1), (1, 0)]
dstr = ['u', 'r', 'l', 'd']
class Point:
def __init__(self, distance, coordinates, directions):
self.distance = distance
self.coordinates = coordinates
self.directions = directions
def __eq__(self, p):
if self.distance == p.distance:
return self.__lt__(self, p)
return self.distance - p.distance
def __lt__(self, p):
return len(self.directions) - len(p.directions)
heap = [(Point(0, start, ""))]
visited = set()
while heap:
point = heapq.heappop(heap)
dist = point.distance
node = point.coordinates
directions = point.directions
if node in visited: continue
if node == destination:
return directions
visited.add(node)
for idx, move in enumerate(moves):
dx, dy = move
newX = node[0]
newY = node[1]
distance = dist
newDirections = directions
while 0 <= newX + dx < row and 0 <= newY + dy < col and maze[newX + dx][newY + dy] == 0:
newX += dx
newY += dy
distance += 1
if (newX, newY) == destination:
break
if (newX, newY) not in visited:
heapq.heappush(heap, Point(distance, (newX, newY), newDirections + dstr[idx]))
return "Impossible"
path = shortestDistance(maze, start, end)
print(path)
这个想法是比较距离,如果相等,则选择方向变化较少的路径。
我目前正在将rdrludlrdrudludldldr(即右下右左-...)作为输出,但在索引 2 处找到的序列“rl”没有意义:“右”不应该是后跟“左”也不应该“上”后跟“下”,反之亦然。这样的顺序显然不是最优的,因为这两个动作中的第一个可以省略,以使球在相同的位置并移动更短的距离。
这个迷宫的预期输出是drururdrdrurdrd。
为什么我没有得到最短路径?
【问题讨论】:
-
尝试创建一个尽可能小的失败示例,然后开始调试。
-
虽然您的建议可用于测试,但输出清楚地表明还有其他问题,不幸的是。我无法理解算法背后的逻辑来修复它,我确信这是某个地方的一个小错误。
-
就像您之前的问题一样,您有未定义的变量。请问,在 Stack Overflow 上发布之前,我们能否要求您仔细检查您的代码是否存在这些明显的错误?
-
什么是未定义的变量好先生?感谢您在 Stack Overflow 上关注我以尝试解决我的问题,我只希望对实际算法如此专注的人出现在这里。
-
x, y 没有定义。我已经在你之前的问题中提到了这一点。
标签: python algorithm breadth-first-search path-finding maze