解决迷宫的 BFS 算法不起作用,多次检查相同的数字
Maze-solving BFS algorithm not working, checks the same number a lot of times
我正在尝试创建一个迷宫解决算法。网上看了一些教程,接触到了BFS算法。我尝试自己实现它。这是我写的:
import queue, numpy, time
from PIL import Image
def maze(mazename, start=True, end=True):
q = queue.Queue()
img = Image.open(mazename)
array = numpy.array(img).tolist()
for x, y in enumerate(array):
for i, h in enumerate(y):
if h == 0:
array[x][i] = (0, 0, 0)
else:
array[x][i] = (255, 255, 255)
if start and end:
for x, y in enumerate(array[0]):
if y == (255, 255, 255):
start = [x+1, 1]
for x, y in enumerate(array[-1]):
if y == (255, 255, 255):
end = [x+1, len(array)]
start[0] = start[0]-1
start[1] = start[1]-1
end[0] = end[0]-1
end[1] = end[1]-1
start = tuple(start)
q.put("")
while True:
#Checking for end
parse = q.get()
m = list(start)
for i in parse:
if i == "D":
m[1] = m[1]+1
if i == "U":
m[1] = m[1]-1
if i == "L":
m[0] = m[0]-1
if i == "R":
m[0] = m[0]+1
print(m, end)
if m == end:
m = list(start)
array[m[1]][m[0]] = (255, 0, 0)
for i in parse:
if i == "D":
m[1] = m[1]+1
array[m[1]][m[0]] = (255, 0, 0)
if i == "U":
m[1] = m[1]-1
array[m[1]][m[0]] = (255, 0, 0)
if i == "L":
m[0] = m[0]-1
array[m[1]][m[0]] = (255, 0, 0)
if i == "R":
m[0] = m[0]+1
array[m[1]][m[0]] = (255, 0, 0)
return array
#Find new trails
directions = ["U", "D", "L", "R"]
if m[0] == 0:
directions.remove("L")
elif array[m[1]][m[0]-1] == (0, 0, 0):
directions.remove("L")
if m[0]+1 == len(array[0]):
directions.remove("R")
elif array[m[1]][m[0]+1] == (0, 0, 0):
directions.remove("R")
if m[1] == 0:
directions.remove('U')
elif array[m[1]-1][m[0]] == (0, 0, 0):
directions.remove('U')
if m[1]+1 == len(array):
directions.remove("D")
elif array[m[1]+1][m[0]] == (0, 0, 0):
directions.remove("D")
for direction in directions:
q.put(parse+direction)
t1 = time.time()
arr = maze(input("Enter maze file name: "))
print(time.time()-t1)
Image.fromarray(numpy.array(arr).astype(numpy.uint8)).show()
我在这张图片上试过了:https://raw.githubusercontent.com/mikepound/mazesolving/master/examples/tiny.png
它工作得很好。花了 3 到 7 秒。
然后我在这张图片上试了一下:
https://raw.githubusercontent.com/mikepound/mazesolving/master/examples/normal.png
已经运行过去15分钟了,40x40图片的第10行还没有过一次。它检查相同的数字数百次,我不明白为什么。有人可以指出我算法中的缺陷并帮助我修复它吗?我试过实现一个访问过的列表,它只会减慢程序的速度。谢谢
您缺少 visited
的列表。您应该记录到目前为止您去过的地方,以免重复相同的地点。
当您有一个访问过的列表时,您可以使用它来检查您在移动之前是否已经到达该像素。
def maze(mazename, start=True, end=True):
q = queue.Queue()
visited = []
img = Image.open(mazename)
array = numpy.array(img).tolist()
for x, y in enumerate(array):
for i, h in enumerate(y):
if h == 0:
array[x][i] = (0, 0, 0)
else:
array[x][i] = (255, 255, 255)
if start and end:
for x, y in enumerate(array[0]):
if y == (255, 255, 255):
start = [x+1, 1]
for x, y in enumerate(array[-1]):
if y == (255, 255, 255):
end = [x+1, len(array)]
start[0] = start[0]-1
start[1] = start[1]-1
end[0] = end[0]-1
end[1] = end[1]-1
start = tuple(start)
q.put("")
while True:
#Checking for end
parse = q.get()
m = list(start)
for i in parse:
if i == "D":
m[1] = m[1]+1
if i == "U":
m[1] = m[1]-1
if i == "L":
m[0] = m[0]-1
if i == "R":
m[0] = m[0]+1
if m not in visited:
visited.append(m)
print(m, end)
if m == end:
m = list(start)
array[m[1]][m[0]] = (255, 0, 0)
for i in parse:
if i == "D":
m[1] = m[1]+1
array[m[1]][m[0]] = (255, 0, 0)
if i == "U":
m[1] = m[1]-1
array[m[1]][m[0]] = (255, 0, 0)
if i == "L":
m[0] = m[0]-1
array[m[1]][m[0]] = (255, 0, 0)
if i == "R":
m[0] = m[0]+1
array[m[1]][m[0]] = (255, 0, 0)
return array
#Find new trails
directions = ["U", "D", "L", "R"]
if m[0] == 0:
directions.remove("L")
elif array[m[1]][m[0]-1] == (0, 0, 0):
directions.remove("L")
if m[0]+1 == len(array[0]):
directions.remove("R")
elif array[m[1]][m[0]+1] == (0, 0, 0):
directions.remove("R")
if m[1] == 0:
directions.remove('U')
elif array[m[1]-1][m[0]] == (0, 0, 0):
directions.remove('U')
if m[1]+1 == len(array):
directions.remove("D")
elif array[m[1]+1][m[0]] == (0, 0, 0):
directions.remove("D")
for direction in directions:
q.put(parse+direction)
我正在尝试创建一个迷宫解决算法。网上看了一些教程,接触到了BFS算法。我尝试自己实现它。这是我写的:
import queue, numpy, time
from PIL import Image
def maze(mazename, start=True, end=True):
q = queue.Queue()
img = Image.open(mazename)
array = numpy.array(img).tolist()
for x, y in enumerate(array):
for i, h in enumerate(y):
if h == 0:
array[x][i] = (0, 0, 0)
else:
array[x][i] = (255, 255, 255)
if start and end:
for x, y in enumerate(array[0]):
if y == (255, 255, 255):
start = [x+1, 1]
for x, y in enumerate(array[-1]):
if y == (255, 255, 255):
end = [x+1, len(array)]
start[0] = start[0]-1
start[1] = start[1]-1
end[0] = end[0]-1
end[1] = end[1]-1
start = tuple(start)
q.put("")
while True:
#Checking for end
parse = q.get()
m = list(start)
for i in parse:
if i == "D":
m[1] = m[1]+1
if i == "U":
m[1] = m[1]-1
if i == "L":
m[0] = m[0]-1
if i == "R":
m[0] = m[0]+1
print(m, end)
if m == end:
m = list(start)
array[m[1]][m[0]] = (255, 0, 0)
for i in parse:
if i == "D":
m[1] = m[1]+1
array[m[1]][m[0]] = (255, 0, 0)
if i == "U":
m[1] = m[1]-1
array[m[1]][m[0]] = (255, 0, 0)
if i == "L":
m[0] = m[0]-1
array[m[1]][m[0]] = (255, 0, 0)
if i == "R":
m[0] = m[0]+1
array[m[1]][m[0]] = (255, 0, 0)
return array
#Find new trails
directions = ["U", "D", "L", "R"]
if m[0] == 0:
directions.remove("L")
elif array[m[1]][m[0]-1] == (0, 0, 0):
directions.remove("L")
if m[0]+1 == len(array[0]):
directions.remove("R")
elif array[m[1]][m[0]+1] == (0, 0, 0):
directions.remove("R")
if m[1] == 0:
directions.remove('U')
elif array[m[1]-1][m[0]] == (0, 0, 0):
directions.remove('U')
if m[1]+1 == len(array):
directions.remove("D")
elif array[m[1]+1][m[0]] == (0, 0, 0):
directions.remove("D")
for direction in directions:
q.put(parse+direction)
t1 = time.time()
arr = maze(input("Enter maze file name: "))
print(time.time()-t1)
Image.fromarray(numpy.array(arr).astype(numpy.uint8)).show()
我在这张图片上试过了:https://raw.githubusercontent.com/mikepound/mazesolving/master/examples/tiny.png 它工作得很好。花了 3 到 7 秒。
然后我在这张图片上试了一下: https://raw.githubusercontent.com/mikepound/mazesolving/master/examples/normal.png
已经运行过去15分钟了,40x40图片的第10行还没有过一次。它检查相同的数字数百次,我不明白为什么。有人可以指出我算法中的缺陷并帮助我修复它吗?我试过实现一个访问过的列表,它只会减慢程序的速度。谢谢
您缺少 visited
的列表。您应该记录到目前为止您去过的地方,以免重复相同的地点。
当您有一个访问过的列表时,您可以使用它来检查您在移动之前是否已经到达该像素。
def maze(mazename, start=True, end=True):
q = queue.Queue()
visited = []
img = Image.open(mazename)
array = numpy.array(img).tolist()
for x, y in enumerate(array):
for i, h in enumerate(y):
if h == 0:
array[x][i] = (0, 0, 0)
else:
array[x][i] = (255, 255, 255)
if start and end:
for x, y in enumerate(array[0]):
if y == (255, 255, 255):
start = [x+1, 1]
for x, y in enumerate(array[-1]):
if y == (255, 255, 255):
end = [x+1, len(array)]
start[0] = start[0]-1
start[1] = start[1]-1
end[0] = end[0]-1
end[1] = end[1]-1
start = tuple(start)
q.put("")
while True:
#Checking for end
parse = q.get()
m = list(start)
for i in parse:
if i == "D":
m[1] = m[1]+1
if i == "U":
m[1] = m[1]-1
if i == "L":
m[0] = m[0]-1
if i == "R":
m[0] = m[0]+1
if m not in visited:
visited.append(m)
print(m, end)
if m == end:
m = list(start)
array[m[1]][m[0]] = (255, 0, 0)
for i in parse:
if i == "D":
m[1] = m[1]+1
array[m[1]][m[0]] = (255, 0, 0)
if i == "U":
m[1] = m[1]-1
array[m[1]][m[0]] = (255, 0, 0)
if i == "L":
m[0] = m[0]-1
array[m[1]][m[0]] = (255, 0, 0)
if i == "R":
m[0] = m[0]+1
array[m[1]][m[0]] = (255, 0, 0)
return array
#Find new trails
directions = ["U", "D", "L", "R"]
if m[0] == 0:
directions.remove("L")
elif array[m[1]][m[0]-1] == (0, 0, 0):
directions.remove("L")
if m[0]+1 == len(array[0]):
directions.remove("R")
elif array[m[1]][m[0]+1] == (0, 0, 0):
directions.remove("R")
if m[1] == 0:
directions.remove('U')
elif array[m[1]-1][m[0]] == (0, 0, 0):
directions.remove('U')
if m[1]+1 == len(array):
directions.remove("D")
elif array[m[1]+1][m[0]] == (0, 0, 0):
directions.remove("D")
for direction in directions:
q.put(parse+direction)