2016-05-30 9 views
1

Ich versuche, mein Labyrinth als die Suche nach der Lösung kontinuierlich (das ist eine einfache Uniform-Cost-Suche für ein Labyrinth) zu aktualisieren. Ich verwende pyplots ion(), um meine Abbildung nach jedem Knotenbesuch zu aktualisieren. Mein Problem ist, dass sich die Figur bei etwa 20 Iterationen sehr langsam aktualisiert. Ich habe versucht, den Wert für pause() zu reduzieren, aber es scheint keine Wirkung zu haben. Ich bin mir ziemlich sicher, dass es nicht mein PC ist.Python - Matplotlib.pyplot Ion() langsam

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) 

Antwort

2

Hier ist ein einfaches Beispiel zeigt, wie ein Quadmesh wie die von pcolormesh zurück einer animieren. Alles, was Sie tun müssen (hah!) Ist, ändern Sie step, um die Labyrinthe zu ergeben, die Sie anzeigen möchten.

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() 

Verringern der interval Parameter in FuncAnimation die Verzögerung zwischen Frames zu reduzieren. Dadurch wird die Animation schneller. Sie werden feststellen, dass es kein Problem gibt, wodurch die Animation ziemlich schnell geht.

Obwohl eine einzelne quadmesh Aktualisierung (wie oben geschehen) ist schneller als pcolormesh mehrfach Aufruf mit plt.ion eingeschaltet, der Hauptgrund, warum Ihre Animation langsam geht, weil printMaze(path) die gleiche path oft mit aufgerufen wird.

können Sie diese Behauptung bestätigen printMaze Modifizieren

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

Sie werden sehen, in dem Terminal zu sein, dass das Labyrinth häufig die gleichen viele Zeiten. Um Ihre Animation also schneller zu machen, müssen Sie Ihre uniformCostSearch schlauer machen. verwenden vielleicht einen Satz maze s zu erinnern, haben bereits angezeigt worden ist und nicht nennen printMaze wieder in diesem Fall:

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() 
Verwandte Themen