寻求有关在流行病模拟器中尝试在MATLAB中读取二维细胞自动机的摩尔定律的建议

时间:2019-06-13 16:06:35

标签: matlab cellular-automata

我目前正在编写一个代码,该代码利用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

我希望矩阵会逐渐变得洋红色,但是第二个矩阵什么也没有发生。我第三次收到此错误。

“ ||和&&运算符的运算符必须可转换为逻辑标量值。”

我只是不知道该怎么办!

1 个答案:

答案 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

enter image description here

细胞在指定时间后恢复健康

  • 对此进行建模,最好对未感染的细胞使用0,对被感染的细胞使用正整数,以表明已被感染了多长时间。
  • 细胞被感染指定的迭代次数后会he愈(但可以立即再次感染...)

该代码使用卷积作为前一个,但是现在已经感染的细胞需要与新感染的细胞分开处理,因此使用了真正的摩尔邻域。

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

enter image description here