Step2: 简单的传播模拟
接下来,我们来完成一个有三维可视化的病毒传播模型。先从最简单的开始——我们忽略掉复杂的环境,完成病毒传染的逻辑:人群中有被感染者和未被感染者两种人,当未被感染者距离被感染者一定距离时,有一定概率被感染。
全局定义
首先,我们在全局定义中,申明感染距离(infection_distance )、感染概率(proba_infection)、初始人群数量(nb_people)、初始感染人数(nb_infected_init)等全局变量,并初始化人群代理。
global {
//模拟设置
float step <- 1 #minutes;
geometry shape <- envelope(square(500 #m));
//初始人群数量
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;
//初始化
init {
create people number: nb_people {
speed <- agent_speed;
}
}
}
族群设置
现在,我们来编写人群族的属性与行为,人群中有被感染者和未被感染者两种,应有是否感染的属性,且感染者与被感染者显示为不同颜色,其行为为移动以及距感染者一定距离时有一定概率被感染。
//人群族定义
species people skills: [moving] {
//是否感染
bool is_infected <- false;
//移动行为
reflex move {
//移动行为为无目的漫游
do wander;
}
//当代理人被感染时
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;
}
}
然后,我们在初始化时,将一部分人设置为感染状态。
global {
...
init {
//在人群族中随机寻找nb_infected_init人
ask nb_infected_init among people {
//将其感染状态设置为真
is_infected <- true;
}
}
}
实验设置
最后,在实验设置中编写好需在图形界面调整的参数以及代理族的显示。
//实验设置
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 people;
}
}
}
本节完整代码如下:
model SI_city
global {
//模拟设置
float step <- 1 #minutes;
geometry shape <- envelope(square(500 #m));
//初始人群数量
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;
//初始化
init {
create people number: nb_people {
speed <- agent_speed;
}
//在人群族中随机寻找nb_infected_init人
ask nb_infected_init among people {
//将其感染状态设置为真
is_infected <- true;
}
}
}
//人群族定义
species people skills: [moving] {
//是否感染
bool is_infected <- false;
//移动行为
reflex move {
//移动行为为无目的漫游
do wander;
}
//当代理人被感染时
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 people;
}
}
}
Last updated
Was this helpful?