【问题标题】:Maze-solving BFS algorithm not working, checks the same number a lot of times解决迷宫的 BFS 算法不起作用,多次检查相同的数字
【发布时间】:2020-06-21 20:41:24
【问题描述】:

我正在尝试创建一个迷宫解决算法。我在网上看了一些教程,并遇到了 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 行一次。它检查相同的数字数百次,我不知道为什么。有人可以指出我算法中的缺陷并帮助我修复它吗?我试过实现一个访问列表,它只会减慢程序的速度。谢谢

【问题讨论】:

    标签: python algorithm numpy breadth-first-search maze


    【解决方案1】:

    您缺少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)
    

    【讨论】:

    • 您能否提供一个在我的代码中实现此功能的示例?
    • @Serket 我更新了我的答案。你会需要一些类似的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 2014-05-07
    • 2019-02-01
    相关资源
    最近更新 更多