关于元胞自动机

article/2025/10/12 22:26:25

元胞自动机(cellular automata,CA) 是一种时间、空间、状态都离散,空间相互作用和时间因果关系为局部的网格动力学模型,具有模拟复杂系统时空演化过程的能力。

其实在去年暑假准备国赛的时候试图过自学,但受限于,网上易懂且高效的文档或者视频教学少之又少,且个人学习能力及时间有限,搞得当时的我一头雾水,于是当时的我放弃了学习。

最近准备数学建模比赛的假期中,建模队友让我去学习一下元胞自动机仿真。花了一些时间研究和思考,整理了一些东西。

元胞自动机在笔者看来,最费解的地方在于:

1.关于元胞具体的颜色如何设置

2.如何让元胞自动机应用于具体地区(如森林大火在澳大利亚的实现,即导入澳大利亚的绿植数据)

3.如何让状态矩阵适应较为复杂的规则

近期笔者观看了大量的教学视频和论文文献,根据以上问题做了一些整理,这个过程重新让我认识了元胞自动机的运行过程,并且总结了一套可适用于绝大多数仿真过程的编程框架。 这里就不赘述元胞自动机的基本知识,直接结合以上三个问题几个具体例子来谈一下见解。 (本文均使用MATLAB来实现)

1.关于元胞具体的颜色如何设置

首先,在笔者的个人理解中,元胞随时间变化的过程本质上是矩阵的变换。 状态矩阵中的数值取于一个有限元素的集合(比如在森林火灾元胞自动机中,我们令森林为0,陆地为1,起火点为3)。 而元胞自动机的“颜色”只是为了方便我们观察变化规律而认为设置的“可视化”过程,我们令森林(0)的位置呈现绿色,陆地(1)的位置呈现黄色,起火点(3)的位置呈现红色。

彩色图像中,每个点的颜色受三原色向量[R,G,B]来控制,R,G,B的值浮动于0到1的区间内。 而色彩的两个极端——黑色和白色的RGB向量为[0,0,0]和[1,1,1]。 也就是说,要想在让矩阵中特定大小的数值显现出我们需要的颜色,我们需要给其设置特定的RGB向量。 不难理解,如果一个m \次n大小的矩阵的各个点显现出我们想看到的颜色,我们需要给定一个m\次n\次3的三维矩阵来控制其颜色,即R,G,B从一个向量延申为一个矩阵。

                

这里我们可以运用cat函数来组合其RGB矩阵

遇到具体实现时,我看到很多B站UP或者文档中直接在最后的循环内去分别去变换RGB矩阵,这里我们可以选择编写一个颜色转化函数,输入状态矩阵,将其转化,这样就可以在每次循环内直接变换其状态矩阵,让程序各个函数分工明确,方便我们更好地调试程序的逻辑。以下为森林火灾的颜色变换函数:

function [R,G,B] = transformcolor(b1)
[m,n]=size(b1);    
[R,G]=deal(ones(m,n));
B=zeros(m,n);
R(b1==0)=0;
B(b1==2)=1;
G(b1==3)=0;
end
[R,G,B]=transformcolor(b1);
ch=imagesc(cat(3,R,G,B));

cat函数将三个R,G,B矩阵合成为一个高维矩阵,方便我们可视化当前状态。 

MATLAB图像的R,G,B颜色对照表可参考以下链接:

https://blog.csdn.net/ha_____ha/article/details/103683988

2.如何让元胞自动机应用于具体地区

 其实,导入具体环境的数据可以是一个简单图像处理的过程。以森林大火为例,我们可以在互联网上寻找到各个国家的植被分布图,笔者在自己练习的时候寻找了美国的国家植被分布图,如下:

一种简单的方式便是将彩色图灰化,即将图像(m\timesn\times3) 的三维RGB矩阵转化为(m\timesn)的二维矩阵。(与之前所说的RGB矩阵稍微有所不同,导入图像时的RGB值均为0-255的数值,并不是0-1)

笔者选取了代表红色的R矩阵(选取RGB矩阵中颜色差异最明显的那个),用imshow观测如下

此时,我们可以根据该灰度图进行一个阈值选择:绿色圈出的部分的值多数分布在0-160之间(森林部分),黄色箭头指向的大陆部分的值多数分布在160-245之间,其余部分分布在245-255之间。而空白部分并不属于美国的版图,方便后期变换处理,笔者让国界之外的部分设置为2。

这里使用循环对整个矩阵进行区域划分

a=imread("E:\USEfulEEE\Mathmodel\CA\China\America.jpg"); %读取图像
b3=a(:,:,3);
b2=a(:,:,2);
b1=a(:,:,1);      %分别观察RGB矩阵,选取值差异最明显的那个
imshow(b1)  %imshow(b2);imshow(b3)
[m,n]=size(b1);
for i=1:mfor j=1:nif b1(i,j)<=160b1(i,j)=0;   %绿色(森林)为0elseif b1(i,j)>160&&b1(i,j)<245b1(i,j)=1;   %陆地(可生长为森林的地区)为1elseb1(i,j)=2;   %边界为2endend
end
[R,G,B]=transformcolor(b1);   %状态矩阵的颜色变换
ch0=imagesc(cat(3,R,G,B));    %可视化区域划分过的美国植被图

 区域划分过的矩阵即为我们后期用于做变换的状态矩阵,该过程相当于状态的初始化。

 3.如何让状态矩阵适应较为复杂的规则

思考状态变换的计算机实现的过程是一个较为复杂的逻辑的梳理过程。这里笔者也用一个单独封装的函数来实现每一次的变换过程。

森林火灾元胞机的变化规则为:

1.森林周围8个邻居若有1处为起火状态,该元胞在下一状态就有很大的概率连带起火

2.起火状态在下一个状态会熄灭,转化为陆地

3.每个森林元胞有很小的概率被闪电劈中,并起火

4.每个陆地元胞有很小的概率生长出新的森林

5.美国版图以外的元胞不受任何元胞的影响,一直保持自身状态

我们在每一个新状态的开始,状态转移函数会捕捉旧状态的森林、陆地、起火、版图以外的状态

function new = generatenew(old)
[m,n]=size(old);
treeold=old==0;            %old中森林的位置
landold=old==1;            %old中陆地的位置
fireold=old==3;            %old中起火的位置
lightning=0.000002;        %起火概率
growth=0.001;              %新树生长的概率

有了旧状态,我们要根据规则和旧状态去生成新的状态,即新状态哪些位置为森林,起火,陆地和版图以外。

笔者根据五大规则列写了几个重要的关系式:

1.新状态森林的位置=旧状态森林的位置-新状态起火的位置+长出新森林的位置

2.新状态陆地的位置=旧状态陆地的位置-长出新森林的位置+旧状态起火的位置

3.新状态起火的位置=闪电劈中的位置+旧状态起火连带的起火位置

不难看出,旧状态几种元胞的总量和新状态几种元胞的总量是永远守恒的。

countfire=zeros(m,n);
countfire(2:m-1,2:n-1)=fireold(1:m-2,2:n-1)+fireold(3:m,2:n-1)+fireold(2:m-1,1:n-2)+fireold(2:m-1,3:n);[r,r1]=deal(rand(m,n));
grow=r.*landold;                        %grow在可能生长的地方有值
light=r.*treeold;                       %light在可能起火的地方有值
liandai=(countfire>=1).*r1;
liandai=(liandai>=0.35)&treeold;grownew=(grow>=1-growth);               %新长出树的位置为1,其余为0 
firenew=(light>=1-lightning)|liandai;   %新起火点为闪电劈中的位置+旧起火点连带的位置
land=landold-grownew+fireold;           %陆地的位置为老陆地+火焰烧尽的位置
tree=treeold+grownew -firenew;new=2*ones(m,n);                        %新地初始化全是边框
new(tree==1)=0;
new(land==1)=1;
new(firenew==1)=3;
end

实现了一次状态的转移,我们在主程序里面加入一个for循环或者while循环,来观察该火灾系统持续的变化过程。

PS:注意并行性,我们不能使用循环一个一个改动元胞空间内的元胞状态,会造成前面的改动影响后面的运行。而利用MATLAB矩阵的优势进行改动可以保证速度。(我也试过用循环来依次改动每一个元胞,这样运行的时间成本的确非常高)

hold on;
axis equal
axis tight
axis off
for i=1:100b1=generatenew(b1);[R,G,B]=transformcolor(b1);ch0=imagesc(cat(3,R,G,B));pause(0.0001)
end

变化过程如下演示(转化gif过后有些模糊):

元胞自动机例二——沙化防护林

笔者在bilibili上看到一个比较有趣的元胞自动机仿真,关于防护林的密度、宽度与防止荒漠化能力的关系研究,即仿真防护林的防护效果。UP主对其做了这样一个规则描述:

链接如下:https://www.bilibili.com/video/BV1nK4y1p7BD

 按照之前讲的模板,我进行了编程。

首先将该区域初始化,一个300\times300的区域,100-150的区域为防护林,其左边为沙漠(不可被人所使用),右边为空地(可被人所使用),为方便处理,我们也设置元胞自动机的边界。

在此我们令空地为0,沙漠为1,森林为2,边界为3。

森林区域设置可改变的种植密度,用变量percentage来表示。不难看出,该变量越大,绿色的部分越密。

封装一个如下的颜色匹配函数:

function [R,G,B] = transformcolor(b1)
[m,n]=size(b1);    
[R,G]=deal(ones(m,n));
B=zeros(m,n);
R(b1==0)=0;
B(b1==2)=1;
G(b1==3)=0;
end

然后根据状态改变的规则,列出以下式子:

1.新状态沙漠的位置=旧状态沙漠的位置-沙漠转空地的位置+空地转沙漠的位置

2.新状态空地的位置=旧状态空地的位置-空地转沙漠的位置+沙漠转空地的位置+森林转空地的位置

3.新状态森林的位置=旧状态森林的位置-森林转空地的位置

状态转移函数如下:

function outlinenew = transferarray(outlineold,m,n)
spaceold=outlineold==0;
desertold=outlineold==1;
forestold=outlineold==2;
[count1,count2]=deal(zeros(m,n));
c1=desertold(1:m-2,2:n-1)+desertold(3:m,2:n-1)+desertold(2:m-1,1:n-2)+desertold(2:m-1,3:n);
count1(2:m-1,2:n-1)=c1;     %count1为每个点周围的沙漠数量
c2=forestold(1:m-2,2:n-1)+forestold(3:m,2:n-1)+forestold(2:m-1,1:n-2)+forestold(2:m-1,3:n);
count2(2:m-1,2:n-1)=c2;     %count2为每个点周围的森林数量
r=rand(m,n);
r1=r>0.7;   
%%%%%空地转沙漠%%%%%%
desertadd=spaceold & (count1>=1) & r1 ;
%%%%%沙漠转空地%%%%%%
desertreduce=desertold & (count2>=3) &r1;
%%%%%森林转空地%%%%%%
spacenew=forestold & (count1>=3) & r1;
%%%%%整体变化过程%%%%%%
outlinenew=3*ones(m,n);
outlinenew(desertold+desertadd-desertreduce==1)=1;
outlinenew(forestold-spacenew==1)=2;
outlinenew(spaceold+spacenew-desertadd+desertreduce==1)=0;
end

主函数如下:

clear;clc;
percentage=0.45;    %可调节森林密度
in=zeros(300);
in(:,1:99)=1;
r=rand(300,51);
r(r>=1-percentage)=2;
r(r<1-percentage)=0;
in(:,100:150)=r;
outline=3*ones(302);
outline(2:301,2:301)=in;[R,G,B]=transformcolor(outline);
ch=imagesc(cat(3,R,G,B));
[m,n]=size(outline);
hold on
for i=1:300outline=transferarray(outline,m,n);[R,G,B]=transformcolor(outline);ch=imagesc(cat(3,R,G,B));pause(0.08)
end

运行效果:

1.森林密度小于50%(设定为35%):

可以看出,沙漠迅速突破防护林,侵蚀了人类的可利用土地。

 2.森林密度大于50%(设定为65%):

可以看出,防护林的保护效果很好。

这段文章记录了一个闲人如何度过他无聊的春节,在想的过程中我体会到了很多,也给并不很自信的我带来了一些小小的成就感和自信心。

强推连大数学建模讲座的元胞自动机教程:

https://www.bilibili.com/video/BV1fV411q7SA?from=search&seid=6908856970843696115&spm_id_from=333.337.0.0

元胞自动机(模拟枫叶腐蚀)_哔哩哔哩_bilibili

要继续加油。


http://chatgpt.dhexx.cn/article/sbaA1h55.shtml

相关文章

元胞自动机(数学建模)

一.元胞自动机的概念 元胞自动机(cellular automata&#xff0c;CA) 是一种时间、空间、状态都离散&#xff0c;空间相互作用和时间因果关系为局部的网格动力学模型&#xff0c;具有模拟复杂系统时空演化过程的能力。 元胞自动机是用一系列模型构造的规则构成&#xff0c;只要满…

元胞自动机

一个一个的格子看做是一个个的元胞&#xff0c;他们按照自己的规则自动进行状态改变就是元胞自动机。 定义&#xff1a;是一种时间、空间、状态都离散&#xff0c;空间相互作用和时间因果关系为局部的网格动力学模型&#xff0c;具有模拟复杂系统时空演化过程的能力。 元胞自…

元胞自动机简介(美赛复习一)

为美赛准备&#xff0c;进行元胞自动机的简单回顾。 本文只是简单回顾&#xff0c;可能会进行相关论文复现。 文章目录 一、简介 1.元胞2.元胞空间3.元胞邻居4.边界条件5.规则二、简单例子 一、简介 元胞自动机&#xff1a;是一种时间、空间、状态都离散&#xff0c;空间相互…

【数学建模】元胞自动机(CA)详解 + Matlab代码实现

文章目录 一、什么是元胞自动机&#xff1f;二、图解元胞自动机&#xff1a;三、案例Matlab代码实现&#xff1a;1.奇偶规则2.生命游戏3.森林火灾 一、什么是元胞自动机&#xff1f; 元胞自动机(cellular automata&#xff0c;CA) 是一种时间、空间、状态都离散&#xff0c;空…

迁移学习在金融行业的应用探索

摘要&#xff1a;通过迁移学习技术&#xff0c;解决少量数据&#xff08;较少重叠样本和特征&#xff09;和个性化&#xff08;较少标记&#xff09;的问题&#xff0c;从数据丰富的领域迁移到数据匮乏的领域。通过迁移学习在保证模型准确率的同时&#xff0c;也提高了建造模型…

pytorch之迁移学习

文章目录 1.导入相关的包2.加载数据3.可视化部分图像数据4.训练模型5.可视化模型的预测结果6.场景1&#xff1a;微调ConvNet7.场景2&#xff1a;ConvNet作为固定特征提取器 实际中&#xff0c;基本没有人会从零开始&#xff08;随机初始化&#xff09;训练一个完整的卷积网络&a…

翻译: Transfer learning 迁移学习指南

这是您需要了解的有关经典迁移学习和深度迁移学习的所有信息。阅读本指南可改进您的模型训练并在更短的时间内获得更好的性能。 1. 背景 事情是这样的—— 至少可以说&#xff0c;在处理一项全新的任务时收集大量数据可能具有挑战性。 然而- 仅使用有限数量的训练数据获得…

迁移学习方法学习

目录 迁移学习的基础知识迁移学习的概念迁移学习的分类按目标域标签分按学习方法分按特征分类按离线与在线形式分 迁移学习的基本方法基于样本的迁移基于特征的迁移基于模型的迁移基于关系的迁移 深度迁移学习深度网络的可迁移性最简单的迁移学习——finetune finetune的使用技…

迁移学习实例

上一篇我们介绍了迁移学习的核心思想和流程&#xff0c;我们介绍一个实例来加深理解。 传送门&#xff1a;迁移学习概述 获取预训练模型 pytorch和tensorflow都封装了很多预训练模型。 pytorch通过工具包torchvision.models模块获取&#xff0c;主要包括AlexNet、VGG系列、 Res…

迁移学习与微调的区别

一、迁移学习&#xff1a; 1、从字面意义上理解是知识转移的学习方法&#xff0c;指一种学习方法&#xff1b;类比机器学习、深度学习等等概念&#xff1b; 2、把已训练好的模型参数迁移到新的模型来帮助新模型训练二、微调&#xff1a; 1、从字面意义上理解是小小的调整&…

迁移学习---举一反三

1.概念 迁移学习是指充分考虑数据、任务、或者模型的相似性&#xff0c;将在旧领域学习到的模型&#xff0c;应用到新的领域的一种学习过程。 通俗的讲就是把已经学习训练好的模型参数迁移到新的模型进行训练。考虑到大部分数据或任务是存在相关性的&#xff0c;所以通过迁移…

迁移学习基础

人类具有跨任务传输知识的固有能力。我们在学习一项任务的过程中获得的知识&#xff0c;可以用来解决相关的任务。任务相关程度越高&#xff0c;我们就越容易迁移或交叉利用知识。到目前为止所讨论的机器学习和深度学习算法&#xff0c;通常都是被设计用于单独运作的。这些算法…

学习迁移学习

学习迁移学习 一、相关背景 随着机器学习和数据挖掘不断发展&#xff0c;一个愈加明显的问题出现在人们面前&#xff1a;要想机器学习能够正常运转必须要保证训练集和测试集有相同的特征空间并且同分布。一旦分布改变&#xff0c;大多数模型往往要根据数据重建&#xff0c;这…

联邦迁移学习

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/123573886 一、联邦学习的定义 横向联邦学习和纵向联邦学习要求所有的参与方具有相同的特征空间或样本空间&#xff0c;从而建立起一个有效的共享机器学习模型。然而&#xff0c;在更多的实际情况下&am…

迁移学习(二)

迁移学习综述&#xff08;二&#xff09;&#xff08;学习笔记&#xff09; A Comprehensive Survey on Transfer Learning 1.引言 迁移学习的目标是利用来自相关领域(称为源领域)的知识&#xff0c;以提高学习性能或最小化目标领域中需要的标记示例的数量。知识转移并不总是…

深度学习中的迁移学习介绍

迁移学习(Transfer Learning)的概念早在20世纪80年代就有相关的研究&#xff0c;这期间的研究有的称为归纳研究(inductive transfer)、知识迁移(knowledge transfer)、终身学习(life-long learning)以及累积学习(incremental learning)等。直到2009年&#xff0c;香港科技大学杨…

迁移学习综述

这是我根据北京邮电大学一位博士的讲解视频所归纳的笔记 视频地址&#xff1a;https://www.bilibili.com/video/BV1ct41167kV?spm_id_from333.337.search-card.all.click 正文 我们为什么需要迁移学习&#xff1f; 众所周知&#xff0c;AlphaGo是通过强化学习去训练&#x…

整理学习之深度迁移学习

迁移学习&#xff08;Transfer Learning&#xff09;通俗来讲就是学会举一反三的能力&#xff0c;通过运用已有的知识来学习新的知识&#xff0c;其核心是找到已有知识和新知识之间的相似性&#xff0c;通过这种相似性的迁移达到迁移学习的目的。世间万事万物皆有共性&#xff…

迁移学习简要

什么是迁移学习 迁移学习是一种机器学习方法&#xff0c;就是把任务为A的开发模型作为其的初始点&#xff0c;重新使用在任务为B的开发模型的过程中。迁移学习是通过从已学习的相关任务中转移知识来改进学习的新任务。虽然大多数机器学习的新 算法都是为了解决单个任务而设计的…

迁移学习(Transfer),面试看这些就够了!(附代码)

1. 什么是迁移学习 迁移学习(Transfer Learning)是一种机器学习方法&#xff0c;就是把为任务 A 开发的模型作为初始点&#xff0c;重新使用在为任务 B 开发模型的过程中。迁移学习是通过从已学习的相关任务中转移知识来改进学习的新任务&#xff0c;虽然大多数机器学习算法都…