如何解决迷宫寻路实现BFS没有给出正确的路径
我正在尝试为带球的迷宫获得最短路径:球一直滚动直到撞到墙壁。我使用 Dijkstra 算法将 heapq
用于优先队列。但是,我得到了一条非最佳路径。
这是我的示例输入代码:
maze = [[0,1,0],[0,[1,1],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),-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,end)
print(path)
这个想法是比较距离,如果相等,选择方向变化较少的路径。
我目前正在获取 rdrludlrdrudludldldr
(即右下右左...)作为输出,但在索引 2 处找到的序列“rl”没有意义:“Right”应该后面不能跟“左”,也不应该跟“上”跟“下”,反之亦然。这样的顺序显然不是最佳的,因为可以省略这两个移动中的第一个,以使球在同一位置并移动更短的距离。
这个迷宫的预期输出是drururdrdrurdrd
。
为什么我没有得到最短路径?
解决方法
问题在于 __lt__
函数没有做它应该做的事情。
它应该返回一个布尔值,当 self
被认为小于 p
时为真。当您当前返回一个整数结果时,该结果通常是非零的,您会遇到这样的情况:一对 (p,q) 点将 p
以下是您如何定义它:
def __lt__(self,p):
return ((self.distance,len(self.directions),self.directions) <
< (p.distance,len(p.directions),p.directions))
通过此更改返回的路径是
rdrdldldrdr
简化
您可以使用命名元组,而不是创建类 Point
,这使一切变得更容易(更快)。您只需要更改“属性”的顺序,以便这些点以所需的方式进行比较,即 directions
应该在 coordinates
之前,方向字符串的长度应该有自己的属性:
from collections import namedtuple
# change order of properties so comparison works as intended
Point = namedtuple("Point","distance,length,directions,coordinates")
然后在调用 Point
的地方进行适当的更改:
heap = [Point(0,"",start)]
# ...
heapq.heappush(heap,Point(distance,len(newDirections) + 1,newDirections + dstr[idx],(newX,newY)))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。