1 简介
为了消除礼堂的安全隐患,制定 行之有效的应急预案,有必要对礼堂人群疏散运动进行研究,掌握礼堂人群疏散的一般特点和规律.采用基于二维元胞自动机模型对某高校礼堂发生人群疏散运动进 行仿真,找出影响礼堂人群疏散效率的关键因素,为高校礼堂设计提供支持;为高校礼堂制定突发事件应急预案提供参考.
2 部分代码
function [Occupied, DynField, cur_evacuated] = myUpdate(OccupiedOld, DynFieldOld, StatField, params)
% 在这个函数里面将完成障碍物静止与人员移动
% 这个函数能跑通,本来的update不知道为什么跑不通。
global neibrs;
global neighborFlags;
global inverseNeighbors;
global inverseNeighborFlags;
neibrs = [-1 0 ; +1 0 ; 0 -1; 0 +1; 0 0];
neighborFlags = [1, 2, 4, 8, 16, 0];
inverseNeighbors = [2 1 4 3 0];% 与neibrs互为倒置关系,会在move的32行体现出来
inverseNeighborFlags(1) = 0; % 跟前面的 neighborFlags 相对应
inverseNeighborFlags(2) = 1;
inverseNeighborFlags(4) = 2;
inverseNeighborFlags(8) = 3;
inverseNeighborFlags(16) = 4; % 0 1 0 2 0 0 0 3 0 0 0 0 0 0 0 4
[n, m] = size(OccupiedOld); % 即 n = m = 50.
Occupied = OccupiedOld; % 这里的OccupiedOld就是更新前的Occupied,即evacuation.m中的Occupied。
DynField = DynFieldOld; % 同上。
miu = params(5);% friction parameter = 0.1
cur_evacuated = 0;
for i = 2: n-1% 因为1和n是墙
for j = 2: m-1% 1和m是墙
if(OccupiedOld(i,j) == 0 || OccupiedOld(i,j) == 100) % 找到不是空和障碍物的(i,j)
continue; % 即布置了人的(i,j),不然一直对i,j进行循环
end
% 每循环出一个有人的(i,j),就进一次move,确定移动的方向
[moveI, moveJ, id] = move(OccupiedOld, DynFieldOld, StatField, i, j, params);
if(id ~= 0) % if we moved - to door or to empty cell ,如果不是停步不前,对应的是move里面id=5
id = neighborFlags(id+1);
DynField(i, j) = DynField(i, j)+1;% 该位置有人经过,则Dyn+1
Occupied(i, j) = 0;% 这一点的人走了过后,这个位置的Occupied就又重置为0了
%if not door keep tracking who is in
if ((moveI>1) && (moveI<n) && (moveJ>1) && (moveJ<m))% 如果这个点的下一步,即moveI和moveJ都还在房间内
Occupied(moveI,moveJ) = bitor(Occupied(moveI, moveJ),id);% bitor 是按位逻辑或运算,赋值为之后的惯性方向寻找做铺垫
else
cur_evacuated = cur_evacuated + 1;
end
end
end
end
% resolve conflicts 解决冲突,miu的概率所有人原地不动
% if several pedestrains decided to move to the same cell
% with probability miu all pedestrains stay on thier previous places
% and with probability 1 - miu one random pedestrain moves
for i = 2: n-1
for j = 2: m-1
if(Occupied(i,j) == 0) % 找到不是0的即已经被占据的(i,j)
continue;
end
candidates = zeros(1);
cnt = 1;
for k=1:4 % 为什么k只需要是1:4?
and_ = bitand(Occupied(i,j), neighborFlags(k+1)); % bitand 是按位逻辑且运算
if(and_ == neighborFlags(k+1)) % if somebody entered cell
candidates(cnt) = k; % from direction of k-th neighbor
cnt = cnt + 1;
end
end
if(length(candidates) > 1)
event = rand(1);
if(event > miu) % one moves
% chose moving with equal probability
move_id = randi(length(candidates));
Occupied(i, j) = neighborFlags(candidates(move_id)+1);
if( (i <= 1) || (i >= n) || (j <= 1) || (j >= m)) %if door
cur_evacuated = cur_evacuated-length(candidates)+1;
end
for k=1:length(candidates)
if(k ~= move_id)
[moveI, moveJ] = getNeighbor(i, j, candidates(k));
DynField(moveI, moveJ) = DynField(moveI, moveJ)-1;
Occupied(moveI,moveJ) = 1;
end
end
else % nobody moves
Occupied(i,j) = 0;
if((i <= 1) || (i >= n) || (j <= 1) || (j >= m)) % if door
cur_evacuated = cur_evacuated - length(candidates);
end
for k=1:length(candidates)
[moveI, moveJ] = getNeighbor(i, j, candidates(k));
DynField(moveI, moveJ) = DynField(moveI, moveJ)-1;
Occupied(moveI,moveJ) = 1;
end
end
end
end
end
%update Dynamic field
alpha = params(3); % diffusion of dynamic field
delta = params(4); % decay of dynamic field
for i = 2: n -1
for j = 2: m -1
eventDecay = rand(1);
if(DynField(i,j) == 0) % D must be non-negative
continue;
end
if(eventDecay < delta)
DynField(i, j) = DynField(i, j) - 1; % decay
end
if(DynField(i,j) == 0) % D must be non-negative 非负
continue;
end
eventDiffuse = rand(1);
if(eventDiffuse < alpha)
DynField(i, j) = DynField(i, j) - 1; % diffuse
% choose neight to which boson will move
nightborToDecay = randi(4);
[moveI, moveJ] = getNeighbor(i, j, nightborToDecay);
DynField(moveI, moveJ) = DynField(moveI, moveJ) + 1;
end
end
end
% Occupied=zeros(50,50);
% DynField=zeros(50,50);
% cur_evacuated=0;
end
3 仿真结果
4 参考文献
[1]梅圣显. 基于元胞自动机模型的公共场所人员应急疏散研究. Diss. 哈尔滨工业大学.
博主简介:擅长智能优化算法、神经网络预测、信号处理、元胞自动机、图像处理、路径规划、无人机等多种领域的Matlab仿真,相关matlab代码问题可私信交流。
部分理论引用网络文献,若有侵权联系博主删除。
如果觉得《Matlab实现基于元胞自动机模拟室内人员疏散的最基本模型》对你有帮助,请点赞、收藏,并留下你的观点哦!