hiyouga / hiyouga-blog-project

填坑ing...
http://blog.hiyouga.top
MIT License
7 stars 3 forks source link

MATLAB下实现元胞自动机 #9

Open hiyouga opened 6 years ago

hiyouga commented 6 years ago

最近准备2018MCM/ICM中,看看相关算法… 比赛还剩不到十天了,却感觉自己的算法积累还远远不够,之前也没有太下功夫,只好临阵磨枪了。老实讲真的很不习惯MATLAB的语法结构,总觉得各种混乱,但是却不得不屈服于其简单的一些实现。用Python都没MATLAB快,更别说C++了。 关于元胞自动机: 元胞自动机应该是归类于蒙特卡洛法的一个模拟,引用一段文档里的内容: 元胞自动机(Cellular Automata, CA)是一种用来仿真局部规则和局部联系的方法,也是一种时间和空间都离散的动力系统。典型的元胞自动机是定义在网格上的,每一个点上的网格代表一个元胞与一种有限的状态。变化规则适用于每一个元胞并且同时进行。典型的变化规则,决定于元胞的状态,以及其(4或8个)邻居的状态。元胞自动机已被应用于物理模拟,生物模拟等领域。

首先从Conway的生命游戏机下手:

clc;
clear;

%矩阵大小
n = 512;
z = zeros(n, n);
cells = z;
sum = z;
cells(n/2, .25*n:.75*n) = 1;
cells(.25*n:.75*n, n/2) = 1;
%cells = (rand(n,n))<.5; %用于随机初始化

%绘图相关
imh=image(cat(3,cells,cells,cells));
set(imh,'erasemode','none');
axis equal;
axis tight;

x = 2:n-1;
y = 2:n-1;
for i = 1:100
    sum(x, y) = cells(x,y-1) + cells(x, y+1) + ...
        cells(x-1, y) + cells(x+1, y) + ...
        cells(x-1, y-1) + cells(x-1, y+1) + ...
        cells(x+1, y-1) + cells(x+1, y+1);
    %CA Rule
    cells = (sum==3)|(sum==2&cells);
    set(imh,'cdata',cat(3,cells,cells,cells))
    drawnow
end

gi5f

解析一下这个看起来很弱智的程序:

CA规则: 对周围的 8 个近邻的元胞状态求和 如果总和为2的话,则下一时刻的状态不改变 如果总和为3,则下一时刻的状态为1 否则状态为0


以下还有一些例子:

CA规则: 对8个邻居以及自身求和 如果总和<4或者=5,则下一时刻的状态为0,否则为1 cells = ~((sum< 4) | (sum==5));

CA规则: 对8个邻居求和,元胞本身有一个单独的状态参量,记录它们之前是否有非零状态的邻居。 在0和1之间产生一个随机数r 如果总和>0并且r>阈值,并且元胞从未有过有个非零邻居,则元胞为1,否则保持原状态

pick = rand(0,1);
cells = cells | ((sum>=1) & (pick>=threshold) & (visit==0));
visit = (sum>=1) ;

其他之后再看吧…参考课件在下面,好像有点翻译错误之类的,自己分辨。

元胞自动机与Matlab.pdf


交通流的NaSch模型代码: CA_NaSch.zip