我正在尝试不断寻找解决方案时更新迷宫(这是对迷宫的简单统一成本搜索)。每次访问节点后,我都使用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()