PythonBFS程序不返回网格和路径,在迷宫上有障碍物和解决方案
我导入了一个带有数字的文本文件,如下例所示:PythonBFS程序不返回网格和路径,在迷宫上有障碍物和解决方案,python,algorithm,data-structures,breadth-first-search,maze,Python,Algorithm,Data Structures,Breadth First Search,Maze,我导入了一个带有数字的文本文件,如下例所示: 0 0 0 0 0 1 0 0 3 0 3 0 0 0 3 0 0 0 0 3 0 3 0 0 0 0 3 3 0 3 0 0 0 0 0 0 0 3 3 0 3 0 0 0 0 0 0 0 2 3 3 3 0 3 0 0 0 0 0 0 0 0 0 3 3 3 3 0 3 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3 目标是读取文本文件,将其格式化为一个我能够做到的网格(即10×10的网格),然后对列表列表进行排序,以获得解决方案
0 0 0 0 0 1 0 0 3 0 3 0 0 0 3 0 0 0 0 3 0 3 0 0 0 0 3 3 0 3 0 0 0 0 0 0 0 3 3 0 3 0 0 0 0 0 0 0 2 3 3 3 0 3 0 0 0 0 0 0 0 0 0 3 3 3 3 0 3 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3
目标是读取文本文件,将其格式化为一个我能够做到的网格(即10×10的网格),然后对列表列表进行排序,以获得解决方案,其中数字3是障碍,数字1是起点,数字2是解决方案,我尝试使用BFS算法,代理可以上下左右移动 我试图打印从起点(即1)到最接近的解决方案(即2)所采取的步骤序列。数字的格式为字符串/文本。我编写的程序似乎正在运行,但它从未打印解决方案或终止。要打印为解决方案的移动序列的格式为:
“下移” “向上移动” 等等,每一步都在一条换行线上 我在下面附上我的代码,如能提供任何帮助,将不胜感激
import queue
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])
return result
file_name.close()
def print_grid(result, path=''):
for x, pos in enumerate(result[0]):
if pos == '0':
start = x
i = start
j = 0
pos = set()
for move in path:
if move == 'Move Left':
i -= 1
elif move == 'Move Right':
i += 1
elif move == 'Move Up':
j -= 1
elif move == 'Move Down':
j += 1
pos.add((j, i))
for j, row in enumerate(result):
for i, col in enumerate(row):
if (j, i) in pos:
print('#', end='')
else:
print(col + ' ', end='')
print()
def valid(result, moves):
for x, pos in enumerate(result[0]):
if pos == '0':
start = x
i = start
j = 0
for move in moves:
if move == 'Move Left':
i -= 1
elif move == 'Move Right':
i += 1
elif move == 'Move Up':
j -= 1
elif move == 'Move Down':
j += 1
if not (0 <= i < len(result[0]) and 0 <= j < len(result)):
return False
elif (result[i][j] == '3'):
return False
return True
def find_goal(result, moves):
for x, pos in enumerate(result[0]):
if pos == '0':
start = x
i = start
j = 0
for move in moves:
if move == 'Move Left':
i -= 1
elif move == 'Move Right':
i += 1
elif move == 'Move Up':
j -= 1
elif move == 'Move Down':
j += 1
if result[j][i] == '2':
print('Found: ' + moves)
print_grid(result, moves)
return True
return False
nums = queue.Queue()
nums.put('')
add = ''
result = read_to_grid()
while not find_goal(result, add):
add = nums.get()
for j in ['Move Left', 'Move Right', 'Move Up', 'Move Down']:
put = add + j
if valid(result, put):
nums.put(put)
导入队列
def read_user_input():
file\u name=input('输入文件名:\n')
返回文件名
def read_to_grid():
文件名=读取用户输入()
对于打开的NUM(文件名):
line=list(nums.split())
结果=[]
对于范围内的(0,长度(线),10):
result.append(第[\u10]行)
返回结果
文件名。关闭()
def打印网格(结果,路径=“”):
对于x,枚举中的位置(结果[0]):
如果pos==“0”:
开始=x
i=开始
j=0
pos=set()
对于移入路径:
如果移动=='向左移动':
i-=1
elif move==“向右移动”:
i+=1
elif move==“上移”:
j-=1
elif move==“下移”:
j+=1
位置添加((j,i))
对于j,枚举中的行(结果):
对于i,枚举中的列(行):
如果(j,i)处于位置:
打印(“#”,结束=”)
其他:
打印(列+'',结束='')
打印()
def有效(结果、移动):
对于x,枚举中的位置(结果[0]):
如果pos==“0”:
开始=x
i=开始
j=0
对于移入移动:
如果移动=='向左移动':
i-=1
elif move==“向右移动”:
i+=1
elif move==“上移”:
j-=1
elif move==“下移”:
j+=1
如果不是(0在调试代码时,当涉及到“valid”和“find_goal”函数时,我遇到了一些无休止的循环和其他错误
根据我使用宽度优先搜索的经验,最好将每个点视为一个节点(本例中的坐标)让您的队列由当前正在尝试的路径列表组成。其中,每个路径都是被跨越的每个节点的列表。通常,您不希望在给定路径中多次访问同一节点,因此您必须跟踪此信息,而不是单独的“左”、“右”等
综上所述,我构建了您的代码并创建了一个函数,当给定一个节点(不是3)并考虑该节点是否已被访问时,该函数将返回有效的相邻节点。然后,对于BFS部分,队列以包含起始节点的列表开始(我创建了一个函数以查找1所在的位置)。然后,当队列存在时,BFS将弹出当前路径,获取该路径中的最后一个节点,找到所有有效的相邻节点。对于每个有效的相邻节点,新的路径条目将添加到由旧路径+相邻节点组成的队列中。如果其中一个相邻节点是目标,它将结束搜索并返回路径。我已包括在内路径中的方向信息,以便您可以将其解析出来
这应该打印出一条到最近的2的路径,例如:
[((5, 0), ''), ((5, 1), 'Down'), ((6, 1), 'Right'), ((6, 2), 'Down'), ((7, 2), 'Right'), ((7, 3), 'Down'), ((7, 4), 'Down'), ((7, 5), 'Down')]
您将看到…排序(path\u queue,key=lambda…
该行不需要,但它是一种惰性的队列优先级排序方法,总是尝试最短的当前路径。如果删除它,您将看到仍然得到有效的路径,但路径要长得多
def read_user_input():
file\u name=input('输入文件名:\n')
返回文件名
def read_to_grid():
文件名=读取用户输入()
对于打开的NUM(文件名):
line=list(nums.split())
结果=[]
对于范围内的(0,长度(线),10):
result.append(第[\u10]行)
int_结果=[]
对于i,枚举中的行(结果):
int_result.append([])
对于行中的列:
int_结果[i]。追加(int(col))
返回整数结果
def打印网格(结果,路径=“”):
对于x,枚举中的位置(结果[0]):
如果pos==0:
开始=x
i=开始
j=0
pos=set()
对于移入路径:
如果移动=='向左移动':
i-=1
elif move==“向右移动”:
i+=1
elif move==“上移”:
j-=1
elif move==“下移”:
j+=1
位置添加((j,i))
对于j,枚举中的行(结果):
对于i,枚举中的列(行):
如果(j,i)处于位置:
打印(“#”,结束=”)
其他:
打印(str(col)+'',end='')
打印()
def find_start_节点(网格):
对于i,枚举(网格)中的行:
如果第1行为:
返回((行索引(1),i),“”)
返回(无,无)
def valid_adj(当前节点、网格、已访问):
x=当前节点[0][0]
y=当前节点[0][1]
adj=[]
如果((y+1)<10)和(网格[y+1][x]!=3)和非(任何((x,y+1)在节点中用于访问的节点)):
附加(((x,y+1),“向下”))
如果((x+1)<10)和(网格[y][x+1]!=3)和非(任何((x+1,y)在节点中用于访问的节点)):
附加(((x+1,y),‘右’))
如果((y-1)>=0)和
import queue
# Read name file from user
def read_user_input():
file_name = input('Enter the name of your file :\n')
return file_name
# Read file and return list of list[10]
def read_to_grid():
with open(read_user_input()) as file:
for nums in file:
line = list(nums.split())
return line
# Shows a text grid
def print_grid(result, path=[]):
for x, pos in enumerate(result):
if pos == '1':
start = x
i = start
#j = 0
pos = set()
for move in path:
if move == 'Move Left':
i -= 1
elif move == 'Move Right':
i += 1
elif move == 'Move Up':
i -= 10
elif move == 'Move Down':
i += 10
pos.add(i)
for i, celd in enumerate(result):
if i % 10 == 0:
print()
if i in pos:
print('# ', end='')
else:
print(celd + ' ', end='')
# Validates coordinates and traveled path
def valid(result, moves):
for x, pos in enumerate(result):
if pos == '1':
start = x
i = start % 10
j = start // 10
# Where we start
travel = [(j,i)]
for move in moves:
if move == 'Move Left':
i -= 1
elif move == 'Move Right':
i += 1
elif move == 'Move Up':
j -= 1
elif move == 'Move Down':
j += 1
# Check if we have already been there
if (j, i) in travel:
return False
else:
travel += [(j,i)]
# Check coordinates
if i >= 10 or i < 0 or j >= len(result) // 10 or j < 0:
return False
elif result[i+j*10] == '3':
return False
return True
# Return true if 2 is reached
def find_goal(result, moves):
for x, pos in enumerate(result):
if pos == '1':
start = x
i = start
#j = 0
for move in moves:
if move == 'Move Left':
i -= 1
elif move == 'Move Right':
i += 1
elif move == 'Move Up':
i -= 10
elif move == 'Move Down':
i += 10
if result[i] == '2':
print('Found: ',' '.join(moves))
print_grid(result, moves[0:-1])
return True
return False
nums = queue.Queue()
result = read_to_grid()
add = []
while not find_goal(result, add):
if not nums.empty():
add = nums.get()
for j in ['Move Left', 'Move Right', 'Move Up', 'Move Down']:
put = add + [j]
if valid(result, put):
nums.put(put)
import queue
# Read name file from user
def read_user_input():
file_name = input('Enter the name of your file :\n')
return file_name
# Read file and return list of list[10]
def read_to_grid():
with open(read_user_input()) as file:
for nums in file:
line = list(nums.split())
return line
# Shows a text grid
def print_grid(result, path=[]):
pos = set()
for (x,y), _ in path:
i = x + y*10
pos.add(i)
for i, celd in enumerate(result):
if i % 10 == 0:
print()
if i in pos:
print('# ', end='')
else:
print(celd + ' ', end='')
# Validates coordinates and traveled path
def valid(result, moves):
# Unpack
(i,j), _ = moves[-1]
# Check if already traveled
if any(x == i and y == j for (x,y), __ in moves[:-1]):
return False
# Check coordinates
if i >= 10 or i < 0 or j >= len(result) // 10 or j < 0:
return False
elif result[i+j*10] == '3':
return False
return True
# Return true if 2 is reached
def find_goal(result, moves):
# Unpack
(i,j), _ = moves[-1]
if result[i+j*10] == '2':
#Print moves
output = 'Found: '
for (x,y), _ in moves:
output += " "+_
print(output)
#Print grid
print_grid(result, moves[1:-1])
return True
return False
# Return new position and which movement was done.
def move(pos, dir):
(x, y), _ = pos
if dir == 'Move Left':
x -= 1
elif dir == 'Move Right':
x += 1
elif dir == 'Move Up':
y -= 1
elif dir == 'Move Down':
y += 1
return (x, y), dir
nums = queue.Queue()
result = read_to_grid()
# Find the starting position
for x, pos in enumerate(result):
if pos == '1':
start = x
add = [((start % 10, start // 10),'')]
while not find_goal(result, add):
if not nums.empty():
add = nums.get()
for j in ['Move Left', 'Move Right', 'Move Up', 'Move Down']:
put = add + [move(add[-1],j)]
if valid(result, put):
nums.put(put)