我目前正在编写一个代码,该代码利用2D细胞自动机作为MATLAB中的流行病模拟器。我要实现的主要基本规则是,如果在摩尔邻里中具有1个单元半径的任何邻居被感染,该单元将被感染。但是我似乎无法获得一个好的代码。
基本上,我要对一个具有一个单元半径穆尔邻域的单元格说,如果该邻域中的任何值= 2,则初始单元格将变为2。
我已经尝试在Rosetta代码上使用森林火灾代码作为我代码行为的基础,但效果不是很好。当将规则应用到我的规则时,规则并不能很好地发挥作用。我试过使用mod函数和一系列if循环来附加。我将分别输入一些代码来提供上下文。
老实说,这个示例不能像流行病模拟器那样很好地工作。
matlab
clear; clc;
n = 200;
N = n/2;
E = 0.001; % Creating an arbitrary number for population exposed to
the disease but not infected
p = 1 + (rand(n,n)<E);
%p = ceil(rand(n,n)*2.12) - 1;
% ratio0 = sum(p(:)==0)/n^2;
% ratio1 = sum(p(:)==1)/n^2;
% ratio2 = sum(p(:)==2)/n^2;
% ratio3 = sum(p(:)==3)/n^2;
S = ones(3); S(2,2) = 0;
ff = 0.00000000002;
p(N,N) = 3;
%% Running the simulation for a set number of loops
colormap([1,1,1;1,0,1;1,0,0]); %Setting colourmap to Green, red and
grey
count = 0;
while(count<365) % Running the simulation with limited number of runs
count = count + 1;
image(p); pause(0.1); % Creating an image of the model
P = (p==1); % Adding empty cells to new array
P = P + (p==2).*((filter2(S,p==3)>0) + (rand(n,n)<ff) + 2); % Setting
2 as a tree, ignites based on proximity of trees and random
chance ff
P = P + (p==3); % Setting 3 as a burning tree, that becomes 1,
p = P;
end
第二个想法。这基本上什么也不会返回
matlab
clear;clf;clc;
n = 200;
pos = mod((1:n),n) + 1; neg = mod((1:n)-2,n) + 1;
p = (ceil(rand(n,n)*1.0005));
for t = 1:365
if p(neg,neg) ==2
p(:,:) = 2;
end
if p(:,neg)==2
p(:,:) = 2;
end
if p(pos,neg)==2
p(:,:) = 2;
end
if p(neg,:)==2
p(:,:) = 2;
end
if p(pos,:)==2
p(:,:) = 2;
end
if p(neg,pos)==2
p(:,:) = 2;
end
if p(:,pos)==2
p(:,:) = 2;
end
if p(pos,pos)== 2
p(:,:) = 2;
end
image(p)
colormap([1,1,1;1,0,1])
end
第三,我尝试使用逻辑门来看看是否可行。我不知道逗号是否可以代替。
matlab
clear;clf;clc;
n = 200;
pos = mod((1:n),n) + 1; neg = mod((1:n)-2,n) + 1;
p = (ceil(rand(n,n)*1.0005));
%P = p(neg,neg) + p(:,neg) + p(pos,neg) + p(neg,:) + p(:,:) + p(pos,:)
+ p(neg,pos) + p(:,pos) + p(pos,pos)
for t=1:365
if p(neg,neg)|| p(:,neg) || p(pos,neg) || p(neg,:) || p(pos,:) ||
p(neg,pos) || p(:,pos) || p(pos,pos) == 2
p(:,:) = 2;
end
image(p)
colormap([1,1,1;1,0,1])
end
我希望矩阵会逐渐变得洋红色,但是第二个矩阵什么也没有发生。我第三次收到此错误。
“ ||和&&运算符的运算符必须可转换为逻辑标量值。”
我只是不知道该怎么办!
答案 0 :(得分:1)
我认为
2
,未感染1
; 一种简单的方法是使用二维卷积:
n = 200;
p = (ceil(rand(n,n)*1.0005));
neighbourhood = [1 1 1; 1 1 1; 1 1 1]; % Moore plus own cell
for t = 1:356
p = (conv2(p-1, neighbourhood, 'same')>0) + 1; % update
image(p), axis equal, axis tight, colormap([.4 .4 .5; .8 0 0]), pause(.1) % plot
end
0
,对被感染的细胞使用正整数,以表明已被感染了多长时间。该代码使用卷积作为前一个,但是现在已经感染的细胞需要与新感染的细胞分开处理,因此使用了真正的摩尔邻域。
n = 200;
p = (ceil(rand(n,n)*1.0005))-1; % 0: non-infected. 1: just infected
T = 20; % time to heal
neighbourhood = [1 1 1; 1 0 1; 1 1 1]; % Moore
for t = 1:356
already_infected = p>0; % logical index
p(already_infected) = p(already_infected)+1; % increase time count for infected
newly_infected = conv2(p>0, neighbourhood, 'same')>0; % logical index
p(newly_infected & ~already_infected) = 1; % these just became infected
newly_healed = p==T; % logical index
p(newly_healed) = 0; % these are just healed
image(p>0), axis equal, axis tight, colormap([.4 .4 .5; .8 0 0]), pause(.1) % plot
% infected / non-infected state
end