问题描述
我正在尝试对一个代理执行广度优先搜索,该代理在通过文本文件读入的网格中有 4 次移动。 由于某种原因,我无法让它运行。尽管我按照教科书中的算法进行操作。我是编码新手,任何帮助将不胜感激。 这是我的第一篇 Stack Overflow 帖子,很高兴加入你们:) 请不要烤我:( 编辑**文本在一个文件中,是这样的: 3 0 0 0 0 1 0 0 3 3 3 0 3 0 0 0 0 0 3 3 3 0 3 0 0 0 0 0 3 3 3 0 3 0 0 0 0 0 3 3 3 0 3 0 0 0 0 3 0 3 0 3 0 0 0 0 2 3 3 3 0 3 0 0 0 0 3 3 3 3 0 3 0 0 0 0 3 3 3 3 0 3 2 2 0 0 3 3 3 3 3 3 3 3 2 0 3 3 . 编辑**它目前正在崩溃,我不明白如何修复错误,因为我修复的每个错误都会导致更多错误出现,我只是想让它以“向上移动”、“的顺序显示移动的输出”下移'等
import collections
def read_user_input():
file_name = input('Enter the name of your file :\n')
return file_name
def read_to_grid():
file_name = read_user_input()
for nums in open(file_name):
line = list(nums.split())
result = []
for _ in range(0,len(line),10):
result.append(line[_:_ + 10])
print(result)
return result
file_name.close()
def grid_start_position():
grid = read_to_grid()
for x,pos in enumerate(grid[0]):
if pos == "O":
start = x
return start
def bfs():
grid = read_to_grid()
start = grid_start_position()
queue = collections.deque([[start]])
seen = set([start])
while queue:
path = queue.popleft()
path_moves = ''
x,y = path[-1]
if grid[y][x] == '2':
return path
for x2,y2 in (x + 1,y):
if 0 <= x2 < 10 and 0 <= y2 < 10 and grid[x2][y2] != '3' and (x2,y2) not in seen:
queue.append(path + [(x2,y2)])
path_moves = path_moves + 'Move Up '
seen.add((x2,y2))
for x2,y2 in (x - 1,y2)])
path_moves = path_moves + 'Move Down '
seen.add((x2,y2 in (x,y + 1):
if 0 <= x2 < 10 and 0 <= y2 < 10 and grid[x2][y2] != '3' and (x2,y2)])
path_moves = path_moves + 'Move Right'
seen.add((x2,y - 1):
if 0 <= x2 < 10 and 0 <= y2 < 10 and grid[x2][y2] != '3' and (x2,y2)])
path_moves = path_moves + 'Move Left'
seen.add((x2,y2))
print(path_moves)
bfs()
解决方法
一些问题:
-
grid_start_position
只返回一个 x 坐标,你把start
放在队列中,但在循环中你希望队列有坐标 对 (x 和 y)。您最好更新grid_start_position
以返回 x,y 对。注意:它可能需要在 y 坐标上进行额外的循环,因为您不能确定开始总是在第一行? -
那里有一个
if pos == "O"
条件,它永远不会成立,因为您提供的输入只有 数字 数据,所以没有字母“O”。这可能应该是“0”(零)。 -
您调用
read_to_grid()
两次:一次在bfs
中,然后在grid_start_position
中再次调用。相反,您应该在调用中将网格传递给grid_start_position
。 -
for x2,y2 in (x + 1,y)
将不起作用。您可以说x2,y2 = (x + 1,y)
,但您的in
运算符会尝试将x + 1
解包为两个值。为了避免你的代码重复,你应该做一个这样的循环:for move,x2,y2 in (("Right",x + 1,y),("Left",x - 1,("Up",x,y - 1),("Down",y + 1)):
-
使用
path_moves = path_moves + "some string"
,您不断添加您正在访问的所有 节点到该路径,这是没有意义的:这根本不是一条路径。您需要一种不同的技术,为您访问的每个节点保留反向引用(“我来自哪里”)。然后,当您到达目标时,您应该(只有这样!)根据该信息重建路径。
我不会提供更正后的代码,因为这已经解决了很多次了。例如,您可以从 How do I find shortest path in maze with BFS? 中获得灵感,其中 OP 在构建路径时遇到了类似的问题。