基于元胞自动机(Cellular Automata, CA)的室内人员疏散模拟的MATLAB代码实现,结合核心模型设计、动态规则优化及可视化技术,适用于教室、商场等场景的疏散效率评估。
一、模型核心设计
1. 元胞空间与状态定义
-
网格划分:将室内空间划分为 N×N 的均匀网格,每个元胞代表固定区域(如0.4m×0.4m)。
-
元胞状态:
0:空单元格(可行走区域)1:人员(初始随机分布)2:障碍物(墙壁、家具)3:出口(目标位置)
% 参数初始化
N = 50; % 网格尺寸
density = 0.3; % 人员密度
exit_pos = [N, round(N/2)]; % 出口位置
exit_size = 3; % 出口宽度
% 初始化网格
grid = zeros(N);
grid(randperm(N*N, round(density*N*N))) = 1; % 随机分布人员
grid(exit_pos(1), exit_pos(2)-exit_size:exit_pos(2)+exit_size) = 3; % 设置出口
grid([1,end],:) = 2; grid(:,[1,end]) = 2; % 边界障碍物
2. 移动规则设计
-
方向选择:采用 Moore型邻居(8邻域),行人优先向静态场梯度下降方向移动。
-
静态场计算:基于Dijkstra算法生成距离场,引导人员走向最近出口:
function S = computeStaticField(grid, exit_pos) [rows, cols] = size(grid); S = inf(rows, cols); S(exit_pos(1), exit_pos(2)-exit_size:exit_pos(2)+exit_size) = 0; % 出口处距离为0 % 使用队列传播距离 queue = exit_pos; while ~isempty(queue) [r, c] = queue(1,:); queue(1,:) = []; neighbors = [r-1,c; r+1,c; r,c-1; r,c+1]; % 4邻域 for k = 1:size(neighbors,1) nr = neighbors(k,1); nc = neighbors(k,2); if nr>=1 && nr<=rows && nc>=1 && nc<=cols && grid(nr,nc)~=2 new_dist = S(r,c) + 1; if new_dist < S(nr,nc) S(nr,nc) = new_dist; queue = [queue; nr,nc]; end end end end end
3. 冲突处理机制
- 优先级策略:当多人竞争同一目标格时,按 未移动步数 排序,等待时间最长者优先移动。
- 死锁检测:若人员连续多步未移动,触发随机扰动(随机选择邻域空位)。
二、MATLAB代码
function evacuation_simulation()
% 1. 初始化参数
N = 50; density = 0.3;
exit_pos = [N, round(N/2)]; exit_size = 3;
max_steps = 500;
% 2. 生成网格和静态场
grid = init_grid(N, density, exit_pos, exit_size);
S = computeStaticField(grid, exit_pos);
% 3. 主循环
figure;
evacuated_count = 0;
for t = 1:max_steps
new_grid = grid; % 创建新网格暂存更新
moved = false(size(grid)); % 标记已移动人员
% 遍历所有元胞
for i = 2:N-1
for j = 2:N-1
if grid(i,j) == 1 && ~moved(i,j) % 未移动的人员
% 获取邻居信息
neighbors = get_neighbors(grid, i, j);
if isempty(neighbors), continue; end
% 选择梯度下降方向
[~, idx] = min(S(neighbors(:,1), neighbors(:,2)));
target_r = neighbors(idx,1); target_c = neighbors(idx,2);
% 冲突处理:检查目标格是否被占用
if new_grid(target_r, target_c) == 0
new_grid(i,j) = 0; % 原位置清空
new_grid(target_r, target_c) = 1; % 移动到目标格
moved(target_r, target_c) = true;
end
end
end
end
% 4. 更新网格并检查出口
grid = new_grid;
exit_area = grid(exit_pos(1), exit_pos(2)-exit_size:exit_pos(2)+exit_size);
evacuated = sum(exit_area == 1); % 统计到达出口人数
grid(exit_pos(1), exit_pos(2)-exit_size:exit_pos(2)+exit_size) = 3; % 重置出口
evacuated_count = evacuated_count + evacuated;
% 5. 实时可视化
imagesc(grid);
colormap([1 1 1; 1 0 0; 0.5 0.5 0.5; 0 1 0]); % 白:空, 红:人, 灰:障碍, 绿:出口
title(sprintf('Step: %d, Evacuated: %d', t, evacuated_count));
pause(0.05);
% 终止条件:全部疏散
if evacuated_count >= round(density*N*N)
disp('Evacuation completed!');
break;
end
end
end
% 获取可行邻居列表(8邻域)
function neighbors = get_neighbors(grid, i, j)
offsets = [-1,-1; -1,0; -1,1; 0,-1; 0,1; 1,-1; 1,0; 1,1];
neighbors = [];
for k = 1:size(offsets,1)
ni = i + offsets(k,1); nj = j + offsets(k,2);
if ni>=1 && ni<=size(grid,1) && nj>=1 && nj<=size(grid,2) && grid(ni,nj)~=2
neighbors = [neighbors; ni,nj];
end
end
end
三、关键优化技术
-
动态场融合
-
动态场(D)
:记录人员移动轨迹,通过衰减机制避免路径重复:
D_new = (1 - sigma) * D_current + delta * (sum(neighbor_D)/8); % 衰减与扩散 -
火源场(F):排斥力场引导远离危险源(如火灾位置)。
-
-
路径规划增强
-
A*算法:结合启发式函数优化路径选择,减少绕行:
h = abs(r-exit_r) + abs(c-exit_c); % 曼哈顿距离作为启发函数 f = g + h; % 总代价 = 实际步数 + 启发值
-
-
性能加速技巧
- 向量化计算:用矩阵运算替代循环(如静态场更新用
imfilter)。 - 并行处理:对独立人员移动使用
parfor并行更新。
- 向量化计算:用矩阵运算替代循环(如静态场更新用
四、可视化与结果分析
1. 疏散过程动态显示
-
实时热力图:用
imagesc显示网格状态,颜色编码不同物体。 -
疏散曲线:记录每步疏散人数,绘制时间-人数曲线:
plot(1:t, evacuation_log, 'LineWidth', 2); xlabel('Time Step'); ylabel('Evacuated People');
2. 参数影响分析
| 参数 | 疏散时间变化 | 优化建议 |
|---|---|---|
| 人员密度↑ | 时间指数增长 | 增设出口/拓宽通道 |
| 出口宽度↑ | 时间线性下降 | 最小宽度≥1.2m(建筑规范) |
| 障碍物复杂度↑ | 时间显著增加 | 简化空间布局 |
总结
该模型通过静态场引导、冲突优先级和动态场优化实现高效疏散模拟,核心代码如下:
- 静态场生成 → Dijkstra算法计算最短路径;
- 移动决策 → 梯度下降方向选择;
- 冲突解决 → 等待时间优先策略;
- 可视化 → 热力图动态更新疏散进度。
参考代码与案例:
- 基于元胞自动机进行的室内人员疏散模拟代码 www.youwenfan.com/contentcnc/97613.html