/**
* Name: SI without ODE
* Author:
* Description: A simple SI model without Ordinary Differential Equations showing agents
* moving randomly among a grid and becoming infected
* Tags: grid
*/
model si
global {
int number_S <- 495; // The number of susceptible
int number_I <- 5 ; // The number of infected
float survivalProbability <- 1/(70*365) ; // The survival probability
float beta <- 0.05 ; // The parameter Beta
float nu <- 0.001 ; // The parameter Nu
int numberHosts <- number_S+number_I; //Total number of hosts
bool local_infection <- true ; //Infection spread locally or not
int neighbours_size <- 2 ; //Size of the neighbourhood
geometry shape <- square(50);
init {
//Creation of all the susceptible hosts
create Host number: number_S {
is_susceptible <- true;
is_infected <- false;
is_immune <- false;
color <- rgb(46,204,113);
}
//Creation of all the infected hosts
create Host number: number_I {
is_susceptible <- false;
is_infected <- true;
is_immune <- false;
color <- rgb(231,76,60);
}
}
//Reflex to update the number of infected hosts
reflex compute_nb_infected {
number_I <- Host count (each.is_infected);
}
}
//Grid to discretize space
grid si_grid width: 50 height: 50 use_individual_shapes: false use_regular_agents: false frequency: 0{
rgb color <- #white;
list neighbours <- (self neighbors_at neighbours_size) ;
}
//Species host which represent the possible hosts of a disease
species Host {
//Booleans to represent the state of the agent
bool is_susceptible <- true;
bool is_infected <- false;
bool is_immune <- false;
rgb color <- rgb(46,204,113);
int sic_count <- 0;
si_grid myPlace;
//The agent is placed randomly among the grid
init {
myPlace <- one_of (si_grid as list);
location <- myPlace.location;
}
//Reflex to move the agents in its neighbourhood
reflex basic_move {
myPlace <- one_of (myPlace.neighbours) ;
location <- myPlace.location;
}
//Reflex to infect the agent if it is susceptible and according to the other infected agents
reflex become_infected when: is_susceptible {
float rate <- 0.0;
if(local_infection) {
int nb_hosts <- 0;
int nb_hosts_infected <- 0;
loop hst over: ((myPlace.neighbours + myPlace) accumulate (Host overlapping each)) {
nb_hosts <- nb_hosts + 1;
if (hst.is_infected) {
nb_hosts_infected <- nb_hosts_infected + 1;
}
}
rate <- nb_hosts_infected / nb_hosts;
} else {
rate <- number_I / numberHosts;
}
if (flip(beta * rate)) {
is_susceptible <- false;
is_infected <- true;
is_immune <- false;
color <- rgb(231,76,60);
}
}
//Reflex to kill the agent according to the death rate
reflex shallDie when: flip(nu) {
create species(self) {
myPlace <- myself.myPlace ;
location <- myself.location ;
}
do die;
}
aspect basic {
draw circle(1) color: color;
}
}
experiment Simulation type: gui {
parameter "Number of Susceptible" var: number_S ;// The number of susceptible
parameter "Number of Infected" var: number_I ; // The number of infected
parameter "Survival Probability" var: survivalProbability ; // The survival probability
parameter "Beta (S->I)" var:beta; // The parameter Beta
parameter "Mortality" var:nu ; // The parameter Nu
parameter "Is the infection is computed locally?" var:local_infection ;
parameter "Size of the neighbours" var:neighbours_size ;
output {
layout #split;
display si_display axes: false {
grid si_grid border: #lightgray;
species Host aspect: basic;
}
display chart refresh: every(10#cycles) axes: false {
chart "Susceptible" type: series background: #white style: exploded {
data "susceptible" value: Host count (each.is_susceptible) color: rgb(46,204,113);
data "infected" value: Host count (each.is_infected) color: rgb(231,76,60);
}
}
}
}