clc;clear;
%元胞自动机(奇偶规则)
n=200;%指定边界(大正方形)长度
Se=zeros(n);%想象成一个正方形,里面有很多小格子
Se(n/2-2:n/2,n/2-2:n/2+2)=1;
%初始化中间的点,这里是行为98~102,列为98~102的5X5正方形
Ch=imagesc(Se);
%可视化元胞自动机,doc imagesc查看使用规则(使用缩放颜色显示图像)
axis square
%axis设置坐标轴范围和纵横比;square使用相同长度的坐标轴线。相应调整数据单位之间的增量
Sd=zeros(n+2);%边界上留出2格不让改变,目的在计算邻居时防止超出索引报错
%Sd单纯为了方便计算邻居用的,元胞状态是看Se
while(true) %一直循环,目的是一直重复整个元胞自动机蔓延过程
Sd(2:n+1,2:n+1)=Se;%Sd中行2~201与列2~201是Se的范围200X200
sumValue=Sd(1:n,2:n+1)+Sd(3:n+2,2:n+1)+Sd(2:n+1,1:n)+Sd(2:n+1,3:n+2);
%假设中心点为(a,a),因此它的邻居就是(a-1,a),(a+1,a),(a,a-1),(a,a+1),相加求和即邻居之和
%最终sumValue矩阵每个点的值都是它的邻居之和(元胞自动机的重点,确定邻居)
Se=mod(sumValue,2);%执行元胞状态改变规则,Se里面的值只有0和1
%mod取余,若邻居之和为偶数,则余数为0,若邻居之和为奇数,则余数为1,刚好满足元胞状态改变规则
set(Ch,"cdata",Se)
%set设置图形对象属性
pause(0.03)%暂停执行程序0.03s后继续执行,为了可视化不断重复元胞状态改变的过程
end
运行结果:
clc;clear;
%元胞自动机(生命游戏0代表死,1代表生)
n=200;%指定边界(大正方形)
p=0.4;%每个小格子为0或1的概率
Se=rand(n)<p;%设置初始的元胞状态,返回的是逻辑值0或1
Sd=zeros(n+2);%边界上留出2格不让改变,目的在计算邻居时防止超出索引报错
%Sd单纯为了方便计算邻居用的,元胞状态是看Se
Ph=imagesc(Se);
%可视化元胞自动机,doc imagesc查看使用规则(使用缩放颜色显示图像)
while(true) %一直循环,目的是一直重复整个元胞自动机蔓延过程
Sd(2:n+1,2:n+1)=Se;%Sd中行2~201与列2~201是Se的范围200X200(被替换)
sumValue=Sd(1:n,1:n)+Sd(1:n,2:n+1)+Sd(1:n,3:n+2)+Sd(2:n+1,1:n)+Sd(2:n+1,3:n+2)+Sd(3:n+2,1:n)+Sd(3:n+2,2:n+1)+Sd(3:n+2,3:n+2);
%假设中心点为(a,a),因此它的邻居就是(a-1,a-1),(a-1,a),(a-1,a+1),(a,a-1),(a,a+1),(a+1,a-1),(a+1,a),(a+1,a+1)相加求和即邻居之和
%最终sumValue矩阵每个点的值都是它的邻居之和(元胞自动机的重点,确定邻居)
for i =1:n %因为sumValue是200X200的矩阵
for j=1:n
if sumValue(i,j)==3||(sumValue(i,j)==2&&Se(i,j)==1)
%为生(1)的情况有2个,
% 1、无论是什么格子,只要邻居有3个生即变为生
%2、对于是生的格子,只要邻居有2个生即可继续保持生
Se(i,j)=1;
else %其它任何情况格子都是死
Se(i,j)=0;
end
end
end
set(Ph,"cdata",Se);
%set设置图形对象属性
pause(0.05);%暂停执行程序0.05s后继续执行,为了可视化不断重复元胞状态改变的过程
end
运行结果:
clc;clear;
%元胞自动机(山火蔓延)
%0代表空地,1代表火,2代表树
n=200;%表示森林的矩阵大小
k=30000;%总迭代次数
P0=0.8;%火变成空地的概率
Plight=5*10^(-6);Pgrowth=10^(-3);%闪电和树生长的概率
P1=0.7;%旁边有树,树着火的概率
veg=zeros(n,n)+2;%初始化森林的矩阵,刚开始全为树
imh=image(cat(3,veg,veg,veg));%可视化表示森林的矩阵
%image从数组显示图像;cat串联数组。cat(3,veg,veg,veg)为一个200X200X3的数组
%三维数组可以看成是3片矩阵叠在一起,共3层
Sd=zeros(n+2);%边界上留出2格不让改变,目的在计算邻居时防止超出索引报错
%Sd单纯为了方便计算邻居用的,元胞状态是看veg
for i=1:k
Sd(2:n+1,2:n+1)=veg;%Sd中行2~201与列2~201是veg的范围200X200(被替换)
sumValue=(Sd(1:n,2:n+1)==1)+(Sd(2:n+1,1:n)==1)+(Sd(2:n+1,3:n+2)==1)+(Sd(3:n+2,2:n+1)==1);
%Sd(1:n,2:n+1)==1是判断,返回逻辑值,如果是火即返回1,如果不是火即返回0
%所以当sumValue>0时,说明邻居至少有一个是火,反之,则邻居没有火
for p=1:n
for q=1:n %因为sumValue是200X200的矩阵
if veg(p,q)==2&&((sumValue(p,q)>0&&rand()<P1)||rand()<Plight)
%让方格着火的情况有:
%1、闪电即rand()<Plight,闪电不需要有树就可以着火
%2、当方格为树时即veg(p,q)==2,且邻居是火才有概率着火即sumValue(p,q)>0&&rand()<P1
veg(p,q)=1;
elseif veg(p,q)==1&&rand()<P0
%让方格变为空地的情况有
%在方格是火的前提下,才能有概率的变为空地
veg(p,q)=0;
elseif veg(p,q)==0&&sumValue(p,q)==0&&rand()<Pgrowth
%让方格变为树的情况有
%在方格是空地的前提下,且周围没有火,才有概率的变成树,要同时满足这3个条件
veg(p,q)=2;
end
end
end
set(imh,"cdata",cat(3,(veg==1),(veg==2),zeros(n)));
%set设置图形对象属性,给不同状态方格上不同颜色,方便区分以及观察变化
drawnow%更新图窗并处理回调
end
运行结果: