这几天在网上看到一篇关于随机森林的文章,感觉挺有趣的,就在这简单地总结了一下随机森林,并使用matlab来仿真实现。 随机森林 随机森林使用了元胞自动机模型,其中每个元胞有三种状态:无树、着火、有树。其中每个元胞的演变规则如下: (1)表示有树状态的元胞如果四周有一个元胞表示着火状态,则下一时刻这个元胞位置变为着火状态; (2)已经着火的元胞下一时刻变为空元宝; (3)每一个表示有树状态的元胞以一个很小的概率变为着火状态; (4)每一个空元胞以一定的概率变为有树状态(表示种树) 算法设计策略 在给出代码之前,我想说一下算法的设计策略,尤其是怎样知道一棵树周围的元胞状态。使用一个n*n的矩阵senlin表示森林,其中认为第一列的元胞与最后一列的元胞是连在一起的,第一行的元胞与最后一行的元胞也是连在一起的。元胞的三种状态表示如下: 0:无树;1:着火 2:有数。在判断一棵树是下一时刻否会着火时,基本的想法是判断每一个有树状态的元胞相邻的四个元胞是否会有表示着火状态的,即是否会有1的元胞,我们的做法是先得到每一个位置上面相邻的元胞的表示矩阵,实现这一步只需要将最后一行拿到第一行的位置,其余行往下移动一行即可,同理,我们可以得到每一个位置下面、左边、右边相邻的元胞的表示矩阵。将这四个矩阵相加起来得到一个矩阵,如果某个位置的元素大于0,则表示这个位置会着火,等于0表示不会着火。 matlab实现随机森林的代码
close; clc,clear; n=300; senlin=zeros(300,300); pfire=0.000001;%发生火灾的概率 pplant=0.001;%种树的概率 up=[n 1:n-1];%这两个矩阵用于计算一棵数是否会发生火灾时使用 right=[2:n 1]; img=image(cat(3,senlin,senlin,senlin)); m=annotation('textbox',[0.1 0.1 0.1 0.1],'LineStyle','-','LineWidth',12,'string','123'); %状态说明:0;无树 1:着火 3:有树木 %开始仿真 for i=1:10000 temp=(senlin(up,:)==1)+(senlin(right,:)==1)+(senlin(:,up)==1)+(senlin(:,right)==1);%算出每个位置四周是否会有着火的数目 %更新森林 新的森林=原来的森林-着火的数目+新种的数目 senlin=2*(senlin==2)-((senlin==2)&(temp>0|rand(n,n)<pfire))+2*((senlin==0)&rand(n,n)<pplant); a=find(senlin==2); aa=length(a); b=find(senlin==1); bb=length(b); shu(i)=aa; fire(i)=50*bb;%乘上一个系数是因为火的数量比树木的数量小大多,这两幅图放在一起时看不出或的趋势,乘上30将火的数量扩大, %可以更明显地看出两者 %定义火灾等级 if bb>=0&&bb<=10 str1="森林安全"; elseif bb>10&&bb<=100 str1="火灾发展"; elseif bb>100 str1="森林大火"; end %定义火灾预警等级 if aa>48000||bb>=10 str2="火灾预警:红色预警"; elseif aa<=48000&&aa>42000 str2="火灾预警:黄色预警"; elseif aa>35000&&aa<=42000 str2="火灾预警:蓝色预警"; elseif aa>=0&&aa<=35000 str2="火灾预警:森林安全"; end str=[str1 ; str2];%10是为了在文本框中换行显示str1和str2 %更新图像 set(img,'cdata',cat(3,(senlin==1),(senlin==2),zeros(n,n))); drawnow; figure(2); delete(m);%删除之前的文本框 plot(shu); hold on plot(fire); legend(['绿树的数量:' num2str(aa)],['火的数量' num2str(bb)]); title(['时间T=',num2str(i),'天']); m=annotation('textbox',[0.15 0.8 0.1 0.1],'LineStyle','-','LineWidth',1,'string',str); hold off end某时刻的结果
