Step3: 整合GIS数据
现在,我们在之前简单的传播模型基础上,结合交通仿真的知识,载入GIS数据并使代理人在不同建筑之间沿着路网移动,完成一个城市环境的病毒传播模拟。
载入GIS数据并初始化
global {
//载入GIS数据
file roads_shapefile <- file("../includes/road.shp");
file buildings_shapefile <- file("../includes/building.shp");
//将全局代理形状设置为包括所有道路的矩形
geometry shape <- envelope(roads_shapefile);
...
init{
//从GIS数据创建建筑和道路
create road from: roads_shapefile;
create building from: buildings_shapefile;
//代理人的初始位置设置为随机建筑的任意位置
create people number:nb_people {
speed <- agent_speed;
location <- any_location_in(one_of(building));
}
}
}
接下来,创建道路和建筑族。
//创建建筑族
species building {
aspect default {
draw shape color: #gray border: #black;
}
}
//创建道路族
species road {
aspect default {
draw shape color: #black;
}
}
然后在实验设置中设置显示建筑与道路族。
experiment main_experiment type:gui{
...
output {
display map {
species road ;
species building ;
species people ;
}
}
}
编写人群的移动行为
我们将人群的移动简化为人群在接近9点、12点、18点时为移动高峰期,其他时间呆在建筑里。这里我们引入两个变量: staying_counter
和 staying_coeff
。
staying_counter
:当代理人达到建筑时开始计数,随着时间递增,开始移动时恢复为0。staying_coeff
:接近9点、12点、18点时数值最小,在三个时间段之间递增。staying_counter/staying_coeff
: 代理人开始移动的概率,随着代理人在建筑中的停留时间递增,并在9点、12点、18点时概率最大。
首先在全局定义中,定义staying_coeff
以及路网road_network
,并在创建道路后初始化路网。
global{
...
//路网
graph road_network;
//定义staying_coeff,随着时间递增,并在9点、12点、18点时数值最小
float staying_coeff update: 10.0 ^ (1 + min([abs(current_date.hour - 9), abs(current_date.hour - 12), abs(current_date.hour - 18)]));
...
init{
create road from: roads_shapefile;
//初始化路网
road_network <- as_edge_graph(road);
}
}
然后在人群族中,为代理人编写stay
和move
行为。
species people skills: [moving] {
//增加属性目标点和stay_counter
point target;
int staying_counter;
...
//当没有目标时停留
reflex stay when: target = nil {
//staying_counter随时间递增
staying_counter <- staying_counter + 1;
//以staying_counter / staying_coeff的概率将目标变为随机建筑中的任意地点
if flip(staying_counter / staying_coeff) {
target <- any_location_in (one_of(building));
}
}
//当有目标时开始移动
reflex move when: target != nil{
//沿着路网向目标点出发
do goto target: target on: road_network;
//达到目标点时将目标设为空值,将staying_counter清零
if (location = target) {
target <- nil;
staying_counter <- 0;
}
}
...
}
本节完整代码如下:
model SI_city
global {
//模拟设置
float step <- 1 #minutes;
//载入GIS数据
file roads_shapefile <- file("../includes/road.shp");
file buildings_shapefile <- file("../includes/building.shp");
//将全局代理形状设置为包括所有道路的矩形
geometry shape <- envelope(roads_shapefile);
//初始人群数量
int nb_people <- 500;
//人群速度
float agent_speed <- 5.0 #km/#h;
//感染距离
float infection_distance <- 2.0 #m;
//感染概率
float proba_infection <- 0.05;
//初始感染人数
int nb_infected_init <- 5;
//路网
graph road_network;
//定义staying_coeff,随着时间递增,并在9点、12点、18点时数值最小
float staying_coeff update: 10.0 ^ (1 + min([abs(current_date.hour - 9), abs(current_date.hour - 12), abs(current_date.hour - 18)]));
//初始化
init {
create road from: roads_shapefile;
create building from: buildings_shapefile;
//初始化路网
road_network <- as_edge_graph(road);
create people number:nb_people {
speed <- agent_speed;
location <- any_location_in(one_of(building));
}
//在人群族中随机寻找nb_infected_init人
ask nb_infected_init among people {
//将其感染状态设置为真
is_infected <- true;
}
}
}
//创建建筑族
species building {
aspect default {
draw shape color: #gray border: #black;
}
}
//创建道路族
species road {
aspect default {
draw shape color: #black;
}
}
//人群族定义
species people skills: [moving] {
//是否感染
bool is_infected <- false;
//增加属性目标点和stay_counter
point target;
int staying_counter;
//当没有目标时停留
reflex stay when: target = nil {
//staying_counter随时间递增
staying_counter <- staying_counter + 1;
//以staying_counter / staying_coeff的概率将目标变为随机建筑中的任意地点
if flip(staying_counter / staying_coeff) {
target <- any_location_in (one_of(building));
}
}
//当有目标时开始移动
reflex move when: target != nil{
//沿着路网向目标点出发
do goto target: target on: road_network;
//达到目标点时将目标设为空值,将staying_counter清零
if (location = target) {
target <- nil;
staying_counter <- 0;
}
}
//当代理人被感染时
reflex infect when: is_infected {
//寻找与其相距infection_distance的其他代理
ask people at_distance infection_distance {
//以proba_infection的概率感染
if (flip(proba_infection)) {
is_infected <- true;
}
}
}
//默认显示设置
aspect default {
//显示为半径为5的圆形,感染者为红色,未感染者为绿色
draw circle(5) color: is_infected ? #red : #green;
}
}
//实验设置
experiment main_experiment type: gui {
//参数设置
parameter "Infection distance" var: infection_distance;
parameter "Proba infection" var: proba_infection min: 0.0 max: 1.0;
parameter "Nb people infected at init" var: nb_infected_init;
//输出
output {
//显示设置
display map {
species road ;
species building ;
species people ;
}
}
}
Last updated
Was this helpful?