I am implementing the Biham-Middleton-Levine Traffic Model for testing and have encountered an issue with the speed of my implementation.
import matplotlib.pyplot as plt
from matplotlib import colors
import numpy as np
import random
data = np.random.rand(10, 10) * 20
# create discrete colormap
cmap = colors.ListedColormap(['white','red', 'blue'])
bounds = [-0.5,0.5,1.5,2.5]
norm = colors.BoundaryNorm(bounds, cmap.N)
p = 0.5
iter = 1000
sizex = 10
sizey = 10
road = np.zeros((sizex,sizey))
for posx in range(np.shape(road)[0]):
for posy in range(np.shape(road)[1]):
if random.uniform(0,1)<p:
if random.uniform(0,1)<0.5:
road[posx][posy] = 1
else:
road[posx][posy] = 2
road[1][1]=1
road[1,2]=2
print(road)
def check(posx, posy, surf):
type = surf[posx][posy]
if type == 1:
posx, posy = posy, posx
surf = np.transpose(surf)
if posx+1<np.shape(surf)[0]:
if surf[posx+1][posy] == 0:
surf[posx][posy] = 0
surf[posx+1][posy] = type
elif posx+1 == np.shape(surf)[0]:
if surf[0][posy] == 0:
surf[0][posy] = type
surf[posx][posy] = 0
fig, ax = plt.subplots()
ax.grid(which='major', axis='both', linestyle='-', color='k', linewidth=1)
ax.set_xticks(np.arange(-.5, sizex, 1));
ax.set_yticks(np.arange(-.5, sizey, 1));
ax.set_xticklabels([])
ax.set_yticklabels([])
for iteration in range(iter):
checklist_x = []
checklist_y = []
for posx in range(np.shape(road)[0]):
for posy in range(np.shape(road)[1]):
if road[posx][posy] == 1:
checklist_x.append((posx,posy))
for posx in range(np.shape(road)[0]):
for posy in range(np.shape(road)[1]):
if road[posx][posy] == 2:
checklist_y.append((posx,posy))
for car in checklist_x:
check(car[0],car[1],road)
for car in checklist_y:
check(car[0],car[1],road)
ax.imshow(road, cmap=cmap, norm=norm)
plt.show()
print('done')
My implementation runs very slowly, although this is mostly due to the way that I am drawing the cell grid,
fig, ax = plt.subplots()
ax.grid(which='major', axis='both', linestyle='-', color='k', linewidth=1)
ax.set_xticks(np.arange(-.5, sizex, 1));
ax.set_yticks(np.arange(-.5, sizey, 1));
ax.set_xticklabels([])
ax.set_yticklabels([])
for iteration in range(iter):
checklist_x = []
checklist_y = []
for posx in range(np.shape(road)[0]):
for posy in range(np.shape(road)[1]):
if road[posx][posy] == 1:
checklist_x.append((posx,posy))
for posx in range(np.shape(road)[0]):
for posy in range(np.shape(road)[1]):
if road[posx][posy] == 2:
checklist_y.append((posx,posy))
for car in checklist_x:
check(car[0],car[1],road)
for car in checklist_y:
check(car[0],car[1],road)
ax.imshow(road, cmap=cmap, norm=norm)
plt.show()
print('done')
The cell grid is redrawn over every iteration, which is very intensive, and greatly outweighs the computation time for working out in array form what the next iteration should be. Is there any way to cache or otherwise avoid redrawing the entire thing every step?