元胞自动机
代码详解
以森林火灾演示为实例理解,以下是从一博客找到的代码。
森林火灾的元胞自动机模型有三种状态:
空位=0
燃烧着的树木=1
树木=2
n=30;
plight=.000005;pgrowth=.01;
ul=[n,1:n-1];
dr=[2:n,1];
veg=zeros(n,n);
imh=image(cat(3,veg,veg,veg));
for i=1:3000
sum=(veg(ul,:)==1)+(veg(:,ul)==1)+(veg(dr,:)==1)+(veg(:,dr)==1);
veg=2*(veg==2)-((veg==2)&(sum>0|(rand(n,n)<plight)))+2*((veg==0)&rand(n,n)<pgrowth);
set(imh,'cdata',cat(3,(veg==1),(veg==2),zeros(n)))
drawnow
pause(0.01)
end
代码出处: 元胞自动机森林演示.
分析
veg(ul,:)==1 对应树=1的下位置
sum=(veg(ul,:)==1)+(veg(:,ul)==1)+(veg(dr,:)==1)+(veg(:,dr)==1);
作用:树=1的状态对其上下左右四个位置的影响。
即规则1:如果某树木元胞的4个邻居有燃烧着的,那么该元胞下一时刻的状态是燃烧着的。
randn()是均值为0方差为1的正态分布,若概率小于闪电发生的概率就为1,大于发生则为0。
rand(n,n)<plight即随机生成的概率小于闪电的概率,为1。发生闪电的概率为0。
(veg==2)&(sum>0|(rand(n,n)<plight))
即判断着火的树。
在是树的条件下,若根据规则1变化sum>0,则下一刻变成燃烧的树,或发生闪电将树变成燃烧的树。两种情况都不满足,则无燃烧的树。
veg==0
空元胞所在位置为1,有树的位置变为0。
rand(n,n)<pgrowth
随机生成概率小于生长变成新树的概率为1,变成新树的为0。
((veg==0)&rand(n,n)<pgrowth)
即判断新生成的树。
条件:原来为空元胞且发生生长的概率大于pgrowth。即1&0=0。
1&1=1,其余为0。
不生长依旧为空元胞的位置为1,其他位置为0。
即所有空元胞以一个低概率变成树木(以模拟新的树木的生长)。
veg=2*(veg== 2)-((veg== 2)&(sum>0|(rand(n,n)<plight)))+2*((veg==0)&rand(n,n)<pgrowth);
即更新森林矩阵规则:树 = 树 - 着火的树 + 新生的树
set(imh,‘cdata’,cat(3,(veg= =1),(veg==2),zeros(n)))
'cdata’是属性标签。
cat命令建立一个RGB图像。
得到的树veg ==1 的位置即燃烧的树在图上显示为红色,veg ==0的位置显示为黑色,veg= =2的位置显示为绿色。
调试发现,因为生长Pgrowth概率大,所以空位变成树的概率大,可以发现黑色的图上绿点逐渐增加。
matlab中set语句用于给某对象的属性进行赋值。具体到set(A,‘CData’,B):
A代表一个对象,'CData’是对象A的其中一个属性,B是准备赋给’CData’的值。
GUI对象中,'CData’通常是在控件对象上显示的真彩色图像,使用矩阵表示。