我正在尝试不断寻找解决方案时更新迷宫(这是对迷宫的简单统一成本搜索)。每次访问节点后,我都使用pyplots ion()更新我的身材。我的问题是,图形在大约20次迭代时更新非常缓慢。我试图减小pause()的值,但似乎没有效果。
我很确定这不是我的PC。

import matplotlib.pyplot as plt
from matplotlib import colors as c
import math
import numpy as np

class Queue:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def enqueue(self, item):
        self.items.insert(0,item)

    def dequeue(self):
        return self.items.pop()

    def size(self):
        return len(self.items)

def euclideanDistance(pos1, pos2):
    return math.sqrt(math.pow((pos2[0]-pos1[0]),2) + math.pow((pos2[1]-pos1[1]),2))

def getChildren(node, maze):
    children = []
    y = node[0]
    x = node[1]
    i = 0
    if y-1 != -1 and maze[y-1][x] != 1 and maze[y-1][x] != 2:
        children.append([])
        children[i].append(y-1)
        children[i].append(x)
        i += 1
    if y-1 != -1 and x+1 != 12 and maze[y-1][x+1] != 1 and maze[y-1][x+1] != 2:
        children.append([])
        children[i].append(y-1)
        children[i].append(x+1)
        i += 1
    if x+1 != 12 and maze[y][x+1] != 1 and maze[y][x+1] != '.':
        children.append([])
        children[i].append(y)
        children[i].append(x+1)
        i += 1
    if y+1 != 12 and x-1 != -1 and maze[y+1][x-1] != 1 and maze[y+1][x-1] != 2:
        children.append([])
        children[i].append(y+1)
        children[i].append(x-1)
        i += 1
    if y+1 != 12 and maze[y+1][x] != 1 and maze[y+1][x] != '.':
        children.append([])
        children[i].append(y+1)
        children[i].append(x)
        i += 1
    if y+1 != 12 and x+1 != 12 and maze[y+1][x+1] != 1 and maze[y+1][x+1] != 2:
        children.append([])
        children[i].append(y+1)
        children[i].append(x+1)
        i += 1
    if x-1 != -1 and maze[y][x-1] != 1 and maze[y][x-1] != 2:
        children.append([])
        children[i].append(y)
        children[i].append(x-1)
        i += 1
    if y-1 != -1 and x-1 != -1 and maze[y-1][x-1] != 1 and maze[y-1][x-1] != 2:
        children.append([])
        children[i].append(y-1)
        children[i].append(x-1)
        i += 1
    return children

def uniformCostSearch(root, goal, maze):
    q = Queue()
    path = maze
    root.append(0)
    q.enqueue(root)
    while not q.isEmpty():
        temp = q.dequeue()
        printMaze(path)
        path[temp[0]][temp[1]] = 2
        if temp[0] == goal[0] and temp[1] == goal[1]:
            return path
        else:
            children = getChildren(temp, path)
            cArray = []
            if len(children) != 0:
                for child in children:
                    child.append(temp[2]+euclideanDistance(temp, child))
                    cArray.append(child)
                cArray.sort(key=lambda x:x[2])
                for child in cArray:
                    q.enqueue(child)

def printMaze(maze):
    y = [12,11,10,9,8,7,6,5,4,3,2,1,0]
    x = [0,1,2,3,4,5,6,7,8,9,10,11,12]
    x, y = np.meshgrid(x, y)
    maze = np.array(maze)
    plt.ion()
    cMap = c.ListedColormap(['w','grey','green','red'])
    plt.xticks([0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5,11.5], [0,1,2,3,4,5,6,7,8,9,10,11])
    plt.yticks([0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5,11.5], [0,1,2,3,4,5,6,7,8,9,10,11])
    plt.pcolormesh(x, y, maze, edgecolor='k',cmap=cMap)
    plt.pause(0.000000001)
    plt.show()

maze = [[0,0,0,0,0,0,0,0,0,0,0,0],
        [0,1,1,1,1,1,1,1,1,1,1,0],
        [0,1,1,1,1,1,1,1,0,3,1,0],
        [0,0,0,0,0,0,1,1,0,0,1,0],
        [0,1,1,0,0,0,1,1,0,0,1,0],
        [0,1,1,0,0,0,1,1,0,0,1,0],
        [0,1,0,0,0,0,1,1,0,0,1,0],
        [0,0,0,0,0,1,1,1,0,0,1,0],
        [0,0,0,0,1,1,1,1,0,0,1,0],
        [0,0,0,1,1,1,1,1,0,0,1,0],
        [0,0,1,1,1,1,1,1,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0]]

root = []
root.append(11)
root.append(0)

goal = []
goal.append(2)
goal.append(9)

printMaze(maze)
uniformCostSearch(root, goal, maze)

最佳答案

这是一个基本示例,显示了如何为Quadmesh设置动画,例如pcolormesh返回的动画。您只需要修改step即可产生想要显示的迷宫。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.animation as animation

def step():
    while True:
        yield np.random.randint(4, size=(N, N))

def animate(data, quadmesh):
    quadmesh.set_array(data.ravel())
    return [quadmesh]

N = 12
maze = np.random.randint(4, size=(N, N))

fig, ax = plt.subplots()
cmap = mcolors.ListedColormap(['w','grey','green','red'])
x, y = np.meshgrid(np.arange(N), np.arange(N))
quadmesh = ax.pcolormesh(x, y, maze, edgecolor='k',cmap=cmap)

ani = animation.FuncAnimation(
    fig, animate, step,
    interval=10, fargs=(quadmesh,), repeat=True, blit=True)
plt.show()


减小interval中的FuncAnimation参数以减少之间的延迟
框架。这将使动画运行得更快。您会发现没有
使动画快速播放的问题。

尽管更新单个quadmesh(如上所述)比调用更快
pcolormesh多次打开plt.ion,这是导致您的
动画进行缓慢是因为printMaze(path)被多次调用
相同的path

您可以通过将printMaze修改为

def printMaze(maze):
    print(maze)
    print('-'*80)


您会在终端上看到迷宫经常是许多
次。因此,为了使动画更快,您需要使
uniformCostSearch更聪明。也许用一套来记住maze
已经显示,在这种情况下不要再次调用printMaze

import math
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.animation as animation

class Queue:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def enqueue(self, item):
        self.items.insert(0,item)

    def dequeue(self):
        return self.items.pop()

    def size(self):
        return len(self.items)

def euclideanDistance(pos1, pos2):
    return math.sqrt(math.pow((pos2[0]-pos1[0]),2) + math.pow((pos2[1]-pos1[1]),2))

def getChildren(node, maze):
    children = []
    y = node[0]
    x = node[1]
    i = 0
    if y-1 != -1 and maze[y-1][x] != 1 and maze[y-1][x] != 2:
        children.append([])
        children[i].append(y-1)
        children[i].append(x)
        i += 1
    if y-1 != -1 and x+1 != 12 and maze[y-1][x+1] != 1 and maze[y-1][x+1] != 2:
        children.append([])
        children[i].append(y-1)
        children[i].append(x+1)
        i += 1
    if x+1 != 12 and maze[y][x+1] != 1 and maze[y][x+1] != '.':
        children.append([])
        children[i].append(y)
        children[i].append(x+1)
        i += 1
    if y+1 != 12 and x-1 != -1 and maze[y+1][x-1] != 1 and maze[y+1][x-1] != 2:
        children.append([])
        children[i].append(y+1)
        children[i].append(x-1)
        i += 1
    if y+1 != 12 and maze[y+1][x] != 1 and maze[y+1][x] != '.':
        children.append([])
        children[i].append(y+1)
        children[i].append(x)
        i += 1
    if y+1 != 12 and x+1 != 12 and maze[y+1][x+1] != 1 and maze[y+1][x+1] != 2:
        children.append([])
        children[i].append(y+1)
        children[i].append(x+1)
        i += 1
    if x-1 != -1 and maze[y][x-1] != 1 and maze[y][x-1] != 2:
        children.append([])
        children[i].append(y)
        children[i].append(x-1)
        i += 1
    if y-1 != -1 and x-1 != -1 and maze[y-1][x-1] != 1 and maze[y-1][x-1] != 2:
        children.append([])
        children[i].append(y-1)
        children[i].append(x-1)
        i += 1
    return children

def step():
    seen = set()
    q = Queue()
    path = maze
    root.append(0)
    q.enqueue(root)
    while not q.isEmpty():
        temp = q.dequeue()
        frozen = tuple(map(tuple, path))
        if frozen not in seen:
            seen.add(frozen)
            yield path
        path[temp[0]][temp[1]] = 2
        if temp[0] == goal[0] and temp[1] == goal[1]:
            return path
        else:
            children = getChildren(temp, path)
            cArray = []
            if len(children) != 0:
                for child in children:
                    child.append(temp[2]+euclideanDistance(temp, child))
                    cArray.append(child)
                cArray.sort(key=lambda x:x[2])
                for child in cArray:
                    q.enqueue(child)


def animate(data, quadmesh):
    quadmesh.set_array(data.ravel())
    return [quadmesh]

maze = np.array([[0,0,0,0,0,0,0,0,0,0,0,0],
                 [0,1,1,1,1,1,1,1,1,1,1,0],
                 [0,1,1,1,1,1,1,1,0,3,1,0],
                 [0,0,0,0,0,0,1,1,0,0,1,0],
                 [0,1,1,0,0,0,1,1,0,0,1,0],
                 [0,1,1,0,0,0,1,1,0,0,1,0],
                 [0,1,0,0,0,0,1,1,0,0,1,0],
                 [0,0,0,0,0,1,1,1,0,0,1,0],
                 [0,0,0,0,1,1,1,1,0,0,1,0],
                 [0,0,0,1,1,1,1,1,0,0,1,0],
                 [0,0,1,1,1,1,1,1,0,0,0,0],
                 [0,0,0,0,0,0,0,0,0,0,0,0]])
root = [11, 0]
goal = [2, 9]

fig, ax = plt.subplots()
x = np.arange(13)
y = x[::-1]
X, Y = np.meshgrid(x, y)
plt.xticks([0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5,11.5], [0,1,2,3,4,5,6,7,8,9,10,11])
plt.yticks([0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5,11.5], [0,1,2,3,4,5,6,7,8,9,10,11])

cmap = mcolors.ListedColormap(['w','grey','green','red'])
quadmesh = ax.pcolormesh(X, Y, maze, edgecolor='k',cmap=cmap)

ani = animation.FuncAnimation(
    fig, animate, step,
    interval=10, fargs=[quadmesh], repeat=False, blit=True)
plt.show()

08-07 16:28