元胞自动机与疏散模型的matlab算法,元胞自动机模拟多出口疏散模型的matlab实现...
2019美赛D题算法之一~
元胞自动机模拟多出口疏散模型的matlab实现
通过设定危险度规则,使用基于双端队列的01bfs算法快速计算每个格子的危险度,使元胞自发地倾向危险度更低的方向来模拟人员疏散模型。
设定规则:自发,社会力,网络
计算危险度:
元胞模拟:概率,社会力
规定
地图:每个小方格对应真实空间中0.4m*0.4m的空间;
地图元素值:0代表墙壁,1代表行人,2代表空格,3及以上的数字代表出口,连续的出口方格具有相同的值,不同的出口值不同。
危险度:按八个方向连通的走法,走到任一出口处所需的步数记为该方格的危险度。
算法流程
读入地图;
计算危险度:以每个出口为起点进行基于双端队列的01bfs算法,使用这种做法可以在O ( 空 方 格 数 ∗ 出 口 个 数 ) O(空方格数*出口个数)O(空方格数∗出口个数)内计算出每个空格的危险度。
算法:
将所有方格的危险度记为-1.
记当前出口编号为3;
初始化队列,将属于该出口的任一方格加入队列头部,记录其危险度为0.
取出队列头所存储的下标,记为当前格。遍历扫描当前格周围的8个格子,记为目标格。
如果目标格与当前格同属于当前出口的方格,那么目标格的预期危险度是0,否则目标格的预期危险度是当前格的危险度+1.
如果目标格的现有危险度是-1或者现有危险度大于预期危险度,就将其的现有危险度置为预期危险度,并将其加入队列:如果预期危险度是0,将其加入队列头,否则加入队列尾。
如果队列不为空,返回4.
如果还有没有访问过的出口,就将出口编号+1然后返回3,否则结束。
通过排序得出危险度从低到高的格子顺序,方便遍历;
依据既定规则向地图内的空格子加入人,产生位置随机,越珍贵的展品附件产生概率越大;
按危险度从低到高的顺序扫描所有格子,如果当前格子内是人,就计算它周围9个格子(包括自身)中未被占据的空格的前进概率,计算方法是β ∗ ( D m − D i ) \beta*(D_m-D_i)β∗(Dm−Di),其中β \betaβ是归一化系数。按这个概率进行决定人下一时刻的位置。到达出口后不再变化。
显示当前时刻的地图状态。
统计未到达出口的人的数量,如果不为0,返回5.。
代码
注:代码已修改。修改后的代码和输入数据见https://download.csdn.net/download/m0_37809890/10945394
% 元胞自动机
clc; clear;
map = map_read();
colormap([0.8 0.8 0.8;1 1 1;1 0 0;0 1 1;0 1 1]);
danger = cal_danger(map);
danger_order = cal_danger_oreder(danger);
map = add_people(map, 0.20);
[K,t] = move(map, danger, danger_order);
function [K,t] = move(map, danger, danger_order)
% 移动
K = zeros(4000,3); t = 0;
map_show(map);
sel = zeros(1,27);
while(size(find(map==1),1))
t=t+1;
K(t,1)=size(find(map(30:110, 340:360 )==1),1);
K(t,2)=size(find(map(3:25, 210:280 )==1),1);
K(t,3)=size(find(map(110:162,420:460 )==1),1);
go = [0,-1; 0,1; -1,0; 1,0; 1,1; 1,-1; -1,1; -1,-1; 0,0];
% flag = 0;
for i = 1:size(danger_order,1)
ua = danger_order(i,1); ub = danger_order(i,2);
if map(ua,ub)~=1
continue;
end
mx = 0; cnt = 0;
for j = 1:size(go,1)
va = ua+go(j,1); vb = ub+go(j,2);
if(map_at(map,va,vb)>1)
mx = max(mx,danger(va,vb));
end
end
for j = 1:size(go,1)
va = ua+go(j,1); vb = ub+go(j,2);
if(map_at(map,va,vb)>1)
for k = 1:mx+1-danger(va,vb)
cnt = cnt+1; sel(cnt)=j;
end
end
end
if(cnt==0)
continue;
end
target = sel(unidrnd(cnt));
va = ua+go(target,1); vb = ub+go(target,2);
map(ua,ub)=2;
if(map(va,vb)==2)
map(va,vb)=1;
end
end
map_show(map);
pause(0.01);
end
end
function res = map_at(map,a,b)
% 如果(a,b)在map内,返回map(a,b),否则返回0
if(a>0&&b>0&&a<=size(map,1)&&b<=size(map,2))
res = map(a,b);
else
res = 0;
end
end
function map = map_read()
% 读入地图
load("./floor_1/map2_2.mat",'A');
map = A';
% map = [
% 0, 0, 0, 0, 0, 0
% 0, 2, 2, 1, 2, 0
% 3, 2, 0, 2, 1, 0
% 0, 2, 2, 2, 1, 0
% 0, 0, 0, 0, 0, 0
% ];
end
function map = add_people(map,rate)
% 向地图里面加人
rnd = rand(size(map));
for i = 1:size(map,1)
for j = 1:size(map,2)
if rnd(i,j)=0)
flag = 0;
for k=size(go,1)
va=ua+go(k,1); vb=ub+go(k,2);
if(map_at(map,va,vb)==0)
flag=1;
break;
end
end
if(flag)
danger(ua,ub)=danger(ua,ub)+0;
end
end
end
end
end
function danger = bfs_01(map,danger,st)
% 01bfs计算单种出口影响的复杂度
n = numel(find(map~=0));
lef=n; rig=n; que = zeros(n*2,2); % 初始化双端队列
que(rig,:)=st; rig = rig+1; %push_back
danger(st(1),st(2)) = 0;
while(lef=1)
nd = danger(ua,ub)+2;
if(danger(ua,ub)==0 && map(ua,ub)==map(va,vb))
nd = 0;
end
if(danger(va,vb)==-1 || danger(va,vb)>nd)
danger(va,vb) = nd;
if(nd==0)
lef=lef-1; que(lef,:)=[va,vb];%push_front
else
que(rig, :)=[va,vb]; rig=rig+1; % push_back
end
end
end
end
end
end
function danger_order = cal_danger_oreder(danger)
% 将危险度进行排序
n = numel(find(danger~=-1));
danger_order = zeros(n,3); k = 1;
for i = 1:size(danger,1)
for j = 1:size(danger,2)
if(danger(i,j)~=-1)
danger_order(k,1) = i;
danger_order(k,2) = j;
danger_order(k,3) = danger(i,j);
k = k + 1;
end
end
end
[~, pos] = sort(danger_order(:,3));
danger_order = danger_order(pos,1:2);
end
元胞自动机与疏散模型的matlab算法,元胞自动机模拟多出口疏散模型的matlab实现...相关推荐
- 【matlab】matlab算法封装成工具包提供给程序调用
说明: 1.非进程通讯协议,无需在电脑上安装完整版的matlab开发环境. 2.本项目以C#为案例,调用的语言不限,操作流程基本相同. 一.准备工作 1.安装MATLABWebAppServerSet ...
- 【元胞自动机】保守策略元胞自动机三车道(不开放辅路,软件园不影响)交通流模型【含Matlab源码 1293期】
⛄一.元胞自动机简介 1 元胞自动机发展历程 最初的元胞自动机是由冯 · 诺依曼在 1950 年代为模拟生物 细胞的自我复制而提出的. 但是并未受到学术界重视. 1970 年, 剑桥大学的约翰 · 何 ...
- 【元胞自动机】激进策略元胞自动机三车道(不开放辅路,软件园不影响)交通流模型【含Matlab源码 1296期】
⛄一.元胞自动机简介 1 元胞自动机发展历程 最初的元胞自动机是由冯 · 诺依曼在 1950 年代为模拟生物 细胞的自我复制而提出的. 但是并未受到学术界重视. 1970 年, 剑桥大学的约翰 · 何 ...
- 【元胞自动机】基于元胞自动机模拟双车道交通流模型含靠右行驶matlab源码
元胞自动机的初步理解 对元胞自动机的初步认识\ 元胞自动机(CA)是一种用来仿真局部规则和局部联系的方法.典型的元\ 胞自动机是定义在网格上的,每一个点上的网格代表一个元胞与一种有限的状\ 态.变化规 ...
- 用matlab做元胞自动机预测,元胞自动机(Cellular Automata)与城市规划及其MATLAB实现——莆田市城市发展预测...
前言 探索元胞自动机用于城市规划,是由于前不久在CSDN上看到相关案例后大开眼界,兴趣使然,想对家乡做一个城市发展预测,遂在巨人的肩膀上做一些探索与更正.文章末尾有这些案例的链接,感谢并致敬这些先行者 ...
- MATLAB演示元胞自动机算法
一.元胞自动机理论 元胞自动机与格子理论是一个非常好的模型,许多复杂的问题都可以通过它来建立模型,下面就简要介绍一下. 元胞自动机 实质上是定义在一个具有离散.有限状态的元胞组成的元胞空间上,并按照一 ...
- 【元胞自动机】元胞自动机车流密度不变下的双向两车道仿真(T 字形路口)【含Matlab源码 1290期】
⛄一.元胞自动机简介 1 元胞自动机发展历程 最初的元胞自动机是由冯 · 诺依曼在 1950 年代为模拟生物 细胞的自我复制而提出的. 但是并未受到学术界重视. 1970 年, 剑桥大学的约翰 · 何 ...
- 如何使用matlab中的胞元数组
胞元数组(cell Arry)的基本组分是胞元(cell),每个胞元本身在数组中是平等的,只能以下标区分.胞元可以存放任何类型.任何大小的数组,如任意维数值数组.字符串数组.符号对象等,而且同一个胞元 ...
- 【matlab】元胞数组(使用celldisp显示元胞数组)
元胞数组(使用celldisp显示元胞数组) 语法格式: celldisp(元胞数组): 我们来看看代码是如何写的: a{1,1}=rand(2,3); a{1,2}=ones(3,5); a{2,1 ...
- matlab创建元胞数组对象,MATLAB中胞元数组的用法
胞元数组(cell Arry)的基本组分是胞元(cell),每个胞元本身在数组中是平等的,只能以下标区分.胞元可以存放任何类型.任何大小的数组,如任意维数值数组.字符串数组.符号对象等,而且同一个胞元 ...
最新文章
- SpringBoot之前端文件管理
- java初始化虚拟机错误_异常 - 虚拟机初始化错误 - Error occurred during initialization of VM...
- 【 FPGA 】7 Series FPGA中对MUX的设计指导
- 利用openCV中的cvCanny函数检测人脸的边缘
- 将MSHFLEXGRID表格中数据导入Excel方法
- Delphi 字符串转十六进制
- 答网友问:如果用 OData 就能直接和 SAP 系统互通,BTP 和 CPI 这样的平台意义在哪里呢?
- head first java原文_Head First Java
- 美团外卖iOS多端复用的推动、支撑与思考
- 打怪升级,在线练习编程的神器!
- 命令行导出数据mysql数据库_MySQL命令行导出数据库
- Hyperledger Fabric Membership Service Providers (MSP)——成员服务
- 【愣锤笔记】基于vue的进阶散点干货
- 计算机做无线AP共享文件,Win7开启AP无线一键共享网络(包括闪讯)给wifi设备使用!...
- 零基础、一次性通过信息系统项目管理师心得与学习计划
- 投资理财书籍推荐 理财书籍排行榜前十
- JAVA 算法中Map 使用技巧,持续更新,边学边更
- ACK (Acknowledge character)数据通信中的确认字符
- 笔记本电脑什么牌子好 世界笔记本电脑排名
- 卡巴斯基2019安装之后电脑网速变慢