從wiki上搜到的Cellular_automaton定義如下:
細胞自動機由單元格的規則網格組成,每個單元格處于有限數量的狀態之一中,諸如開和關(與耦合的地圖網格相反)。網格可以是任何有限數量的維度。對于每個單元格,稱為其鄰域的一組單元格相對于指定的單元格被定義。通過為每個單元分配狀態來選擇初始狀態(時間t= 0)。一個新的一代,創建(前進噸由1),根據一些固定規則(通常數學函數)根據單元格的當前狀態和其鄰域中單元格的狀態來確定每個單元格的新狀態。通常,更新單元狀態的規則對于每個單元是相同的,并且不隨時間改變,并且同時應用于整個網格,盡管已知例外,諸如隨機單元自動機和異步單元自動機。
NaSch模型建立的初衷,是為了解決自敏感性交通流車輛擁堵的特點,采用184規則
184號元胞自動機定義如下:
車輛行駛規則為:黑色元胞表示被一輛車占據
白色表示無車,若前方各自有車,則停止。若前方為空則前進一格,第t時刻到t_1時刻車輛元胞的變化圖解如下
上圖僅顯示了t時刻到t+1時刻車輛元胞的變化過程,現在我們將變化過程逐步分解,稱之為演化規則
從第t時刻車輛的位置至t+1時刻車輛的演化過程如下:
a)加速過程:Vn->(Vn+1,Vmax)
b)安全剎車過程:Vn->(Vn-1,dn-1)
c)隨機變化過程Vn ->max (Vn-1,0)
d)位置更新:Xn ->Xn+Vn
dn =Xn+1 -Xn -L(L為車輛長度)
到這里,各位新人可能看的還是一臉懵逼,結合國賽中實現的三車道換道規則,下面我們依次解釋一下各個演化規則的意義
1)加速:司機總期望以最大的速度行駛
2)安全剎車:為避免與前車發生碰撞
3)隨機慢化(即車輛行駛時不確定因素)
- 過度剎車
- 道路條件變化
- 心里因素
- 延遲因素
4)位置:車輛前進
當Vmax=2時
我們引入下面四個參數,表示單位時間內交通流通過橫斷面流量
probc; % 車輛的密度
B; %單位時間內車流所占用的道路寬度
probslow; % 隨機慢化的概率
Dsafe; % 表示換道事車至少與后面車距離多少個單位才算安全
下面,start making program
模型建立:
close all;
B=3; %The number of the lanes
plazalength=50; %The length of the simulating highways
h=NaN; %h is the handle of the image
[plaza,v]=create_plaza(B,plazalength);
h=show_plaza(plaza,h,0.1);
iterations=1000; % 迭代次數
probc=0.1; % 車輛的密度
probv=[0.1 1]; % 兩種車流的密度分布
probslow=0.3; % 隨機慢化的概率
Dsafe=1; % 表示換道車至少與后面車距離多少個單位才算安全
VTypes=[1,2]; %道路上一共有幾種最大速度不同的車輛,速度是什么
[plaza,v,vmax]=new_cars(plaza,v,probc,probv,VTypes);%一開始就在車道上布置車輛,做周期循環駕駛,也方便觀察流量密度之間的關系
size(find(plaza==1))
PLAZA=rot90(plaza,2);
h=show_plaza(PLAZA,h,0.1);
from 模型 to 編程
之前有講過,元胞自動機是一個動態生成過程
高速公路可以看成一個網格狀視圖,車輛上格子顏色產生變動時,就有車輛消失或生成在邊界(該元胞已經死亡或者生存),我們需要在車輛不斷更新的狀態實時顯示在圖形界面上,
模型轉換的思想就淺顯易懂了,設置兩個車流,一個為正在更新的車流密度,一個為希望此時高速公路能達到的車流密度,其實我們只需要設置兩種車流的密度,因為在更新句柄的過程中,車流的相對密度是相對不變的,詳細會在之后的create_plaza函數中說明
probv=[0.1 1]; % 兩種車流的密度分布
這就要涉及到matlab的GUI函數式編程思想,簡略介紹一下:所謂GUI就是一種用戶界面圖形化操作,我們所使用qq,MSN的聊天界面就屬于GUI,但凡GUI都會有一個活動句柄,每當我們要對窗體就行操作的時候,要更新窗體句柄的活動狀態,通知窗體要對他進行怎樣的改變。
先設計句柄更新后的狀態,引入new_cars.m函數
該函數模型的車道變換規則如下:
(1) 如果vmax>gap,且gapleft≥gap,則從右車道變換至左車道。
(2) 如果 vmax
(3) 如果vback
如果vright>gapleft,則vright=gapleft(禁止右車道的車輛超過左車道車輛)。
old為正在進行仿真的車流密度,entry為希望此時通過橫斷面的車流密度
function new = new_cars(B, L, old, entry)
new = old;
if entry > 0
if entry <= L
x = randperm(L);
y = ceil((B-L)/2+1);
for i = 1:entry
new(1, (y + x(i))) = 1;
end
end
if entry > L
y = ceil((B-L)/2+1);
for i = 1:L
new(1,(y + i)) = 1;
end
end
end