NaSch模型是对184号模型的推广,1992年Nagle和Schreckenberg提出了著名的NaSch模型,在这一模型中,时间、空间以及速度都被离散化,道路被划分为离散的格子(即元胞),每个元胞都是空的,或者被一辆车占据,每辆车的速度可以取1,2,…,Vmax ,Vmax 为最大速度。在时间步增加的过程中,模型按照如下规则进行演化。
Vn —> min(Vn+1, Vmax),直观上的解释是若能加速则速度加一,反应了司机倾向于以尽可能大的速度行驶的特点。
Vn —> min(Vn, Dn),以确保车辆不会与前车发生碰撞。
以随机概率p令Vn —> max(Vn-1,0),该规则用来体现驾驶人的行为差异,这样既可以反映随机加速行为,又可以反映减速过程中的过度反应行为。这一规则也是堵塞自发产生的至关重要因素。
Xn —> Xn+Vn,车辆按照更新后的速度继续向前移动。
用python编写一个NaSch模型代码,并用Matplotlib可视化地绘制成图,并让图像随时间步的推移动态变化。
import matplotlib as mpl
import matplotlib.pyplot as plt
import random
# 创建图像
fig = plt.figure(figsize=(10,1))
# 模型参数设置
numofcell = 20 # 道路长度
numofcar = 12 # 空间中的车辆数
max_time = 100 # 设置最大时间步
max_speed = 5 # 允许的车辆最大速度
p_slowdown = 0.3 # 随机慢化概率
pause_time = 0.1 # 刷新时间(每一帧持续的时间)
cell_size = 15 # 元胞的大小
# 函数:构建一维空间
def Plot_Space():
for i in range(1, numofcell): plt.plot([i-0.5, i-0.5], [-0.5, 0.5], '-k', linewidth = 0.5)
plt.axis([-0.5, numofcell-0.5, -0.5, 0.5])
plt.xticks([]);plt.yticks([])
# 函数:获取和前车的距离
def get_empty_front(link, numofcell, indexofcell):
link2 = link * 2 # 周期性边界
num = 0; i = 1
while (link2[indexofcell + i]) == None:
num += 1; i += 1
return num
# 随机生成初始元胞
Plot_Space()
link = [None] * numofcell
num = 0
while num != numofcar:
sj = random.randint(0, numofcell - 1)
if link[sj] == None:
link[sj] = random.randint(0, 5)
num += 1
# NaSch模型
for t in range(0, max_time):
for cell in range(0, numofcell):
if link[cell] != None:
# 加速
link[cell] = min(link[cell] + 1, max_speed)
# 减速
link[cell] = min(link[cell], get_empty_front(link, numofcell, cell))
# 随机慢化
if random.random() <= p_slowdown:
link[cell] = max(link[cell] - 1, 0)
# 位置更新
nlink = [None] * numofcell
for cell in range(0, numofcell):
if link[cell] != None:
new_index = cell + link[cell]
if new_index >= numofcell:
new_index -= numofcell
nlink[new_index] = link[cell]
link = nlink
x1 = []
for i in range(0,len(link)):
if link[i] != None:
x1.append(i)
Plot_Space()
plt.plot(x1, [0] * numofcar, 'sk', markersize=cell_size)
plt.xlabel('timestep:' + str(t))
plt.pause(pause_time)
plt.cla()
跑一下看看结果!
仔细看,拥堵带是逐渐向后传播的。
操控我的“遥控器”,并给它一个恰当初始状态,元胞就可以开启“阅兵模式”。
给我开“瞬移”挂,只要动的足够快,你就分不清元胞到底是往左跑还是往右跑。
以上就是全部内容啦~
WT酱的所有文章首发于公众号【交通科研Lab】~
获取更多知识请移步观看!