MATLAB做一个简单的元胞自动机:森林火灾模拟
MATLAB做一个简单的元胞自动机:森林火灾模拟
% 简单元胞自动机 - 森林火灾模拟
% 状态: 0=空地, 1=树木, 2=燃烧, 3=灰烬clear; clc; close all;% 参数设置
grid_size = 100; % 网格大小
p_tree = 0.6; % 初始树木概率
p_ignition = 0.0001; % 自燃概率
p_regrowth = 0.01; % 树木再生概率
num_steps = 500; % 模拟步数% 初始化网格
forest = zeros(grid_size);
forest(rand(grid_size) < p_tree) = 1; % 随机放置树木% 创建图形窗口
figure;
colormap([0 0 0; 0 1 0; 1 0 0; 0.5 0.5 0.5]); % 黑,绿,红,灰
h_image = imagesc(forest);
axis equal;
title('森林火灾模拟 - 元胞自动机');
xlabel('点击图形开始模拟');
colorbar('Ticks',[0.375,1.125,1.875,2.625],...'TickLabels',{'空地','树木','燃烧','灰烬'});% 等待用户点击开始
waitforbuttonpress;% 模拟循环
for step = 1:num_stepsnew_forest = forest;for i = 1:grid_sizefor j = 1:grid_size% 获取当前细胞状态current_state = forest(i,j);% 定义邻居位置(摩尔邻居,包括对角线)neighbors = forest(max(i-1,1):min(i+1,grid_size),...max(j-1,1):min(j+1,grid_size));% 计算燃烧邻居数量burning_neighbors = sum(neighbors(:) == 2) - (current_state == 2);switch current_statecase 0 % 空地% 以一定概率生长新树if rand < p_regrowthnew_forest(i,j) = 1;endcase 1 % 树木% 如果有燃烧邻居或自燃,则开始燃烧if burning_neighbors > 0 || rand < p_ignitionnew_forest(i,j) = 2;endcase 2 % 燃烧% 燃烧后变为灰烬new_forest(i,j) = 3;case 3 % 灰烬% 以一定概率变为空地if rand < p_regrowth/2new_forest(i,j) = 0;endendendend% 更新森林状态forest = new_forest;% 更新图形set(h_image, 'CData', forest);title(['步数: ' num2str(step) ' / ' num2str(num_steps)]);drawnow;% 计算统计数据stats(step,:) = [sum(forest(:)==0), sum(forest(:)==1), ...sum(forest(:)==2), sum(forest(:)==3)];% 如果没有燃烧的树木,可能提前结束if sum(forest(:)==2) == 0 && step > 50break;endpause(0.05); % 控制动画速度
end% 绘制统计图表
figure;
steps = 1:step;
plot(steps, stats(1:step,1), 'k-', 'LineWidth', 2); hold on;
plot(steps, stats(1:step,2), 'g-', 'LineWidth', 2);
plot(steps, stats(1:step,3), 'r-', 'LineWidth', 2);
plot(steps, stats(1:step,4), 'Color',[0.5 0.5 0.5], 'LineWidth', 2);
legend('空地', '树木', '燃烧', '灰烬', 'Location', 'best');
xlabel('时间步');
ylabel('细胞数量');
title('状态统计');
grid on;% 显示最终统计信息
fprintf('\n模拟结果统计:\n');
fprintf('总步数: %d\n', step);
fprintf('空地: %d (%.1f%%)\n', stats(end,1), 100*stats(end,1)/(grid_size^2));
fprintf('树木: %d (%.1f%%)\n', stats(end,2), 100*stats(end,2)/(grid_size^2));
fprintf('灰烬: %d (%.1f%%)\n', stats(end,4), 100*stats(end,4)/(grid_size^2));