Skip to content
Snippets Groups Projects
Commit 95ff3a7b authored by AxelCarayon's avatar AxelCarayon
Browse files

merge

parents 89982f74 ddb2ae6f
Branches multibehavior
Tags
No related merge requests found
Showing
with 179 additions and 41 deletions
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
target target
#output files #output files
*.csv src/main/resources/*.csv
*.png src/main/resources/*.png
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid* hs_err_pid*
ODD.md 0 → 100644
# ODD description
## Purpose and patterns
This SMA aims at simulating the spreading of a disease, following the SEIRS model.
The main goal is focused on reproductibility and aim to display what is essential to design and share so our work and results can be reproducted and re-used by others persons.
## Entities, states variables and scales
### Scales
The simulation is executed on a squared environment mesured with an abstract unit size. Size is configurable and there is no minimum or maximum.
In the (optionnal) graphical interpreation, each unit is represented by one pixel.
The simulation step is also an abstract unit and does not represent any real life unit.
The environment can be parametrable to have bounds, wich means that they can't go above the edges. If deactivated, agents wrap to the other side when they go pass a border.
### Entities
There is only one kind of entity in the environment, the **SEIRSAgent**.
Agents move on a random pattern. They will ask the environment wich they are allowed to go (up, down, left or right) and will choose one in random.
There is no collision, multiple agents can be on the same position.
The infestion spead at the individual scale. If an infected agent overlap it's position with another agent, he can spread his disease on him.
Each cycle exposed agents have a chance to become infected.
Each cycle infected agents have a chance to become recovered.
Each cycle recovered agents have a chance to become susceptible.
## Design concepts
### Basic principles
As far as the epidemiological dynamics is concerned, we rely on much scientific evidence that
the disease could be represented by a SEIRS model with an infectious state that can be
presymptomatic or symptomatic, with a certain degree of survivability of the virus
in the environment and the possibility of people being infected by it.
The individual agents’ behavior is very simple and roam aimlessly in random in the environment.
### Emergence
The main emergent (or at least complex to predict) results are the evolution of the number of
infected cases given the different parameters.
In most cases, the 4 differents populations stabilize but when given weak enough infection rate and long enough loosing immunity rate, you can obtain waves.
### Objectives
### Interaction
Agent in the *susceptible* state can be infected if they are in contact with an agent in the *infected* state.
Each susceptible agent in this situation will roll a pseudo-random number between 0 and 1 and if it's bigger than the given number in the parameters, they will switch to the exposed state.
### Observation
A graphical interface can be used if asked in the parameters file.
It will show a window that display the simulation at each step and the total of each population.
Note that it can slow down the speed of the simulation and if the environment is too big for the screen resolution, it won't fit properly.
## Initialization
In order to keep the model as generic as possible, many parameters and initial values are stored in independent external yaml file :
```graphicalMode : Boolean```
When true, will display an IHM when running a simulation
```incubationRate : Float [0..1]```
Chances each cycle that an EXPOSED agent become INFECTED.
```infectionRate : Float [0..1]```
Chances each cycle that an SUCEPTIBLE agent become EXPOSED if an INFECTED agent is nearby.
```looseImmunityRate : Float [0..1]```
Chances each cycle that an RECOVERED agent become SUCEPTIBLE again.
```recoveryRate : Float [0..1]```
Chances each cycle that an INFECTED agent become RECOVERED.
```nbOfCycles : Integer```
Determines for how much cycle the simulation will run.
Setting it to -1 or lower will run the simulation until it's manually stopped.
```nbOfPatientZero : Integer```
Determines how much agents will be already INFECTED when the simulation starts.
```population : Integer```
How much agents will be present in the simuation.
```recordExperiment : Boolean```
If true, the order in wich the agents wake up in the simuation will be recorded.
```playRecord : Boolean```
If true, will use a scheduler that will wake up agents accordingly to the record.
```seed : Integer```
Seed all the random elements in the simulation.
See the [How the random works](#how-the-random-works) section for more details.
```size : Integer```
Set the size in pixels of the square world.
```wrappingWorld : Boolean```
If true, agents will be allowed to wrap to the other side when close to a border.
```synchronousMode : Boolean```
If true, will use a synchronous, seeded scheduler. It is slower but more predictable.
If false, will use a asynchronous scheduler. Faster but results might varies between multiple executions, **even on the same seed**.
```timeBetweenCycles : Boolean```
Delay between each new cycles, in milliseconds. 0 or lower will try make the simulation run as fast as possible.
```infectionStacks : Boolean```
If true, a SUCEPTIBLE agent will roll for infection for **every INFECTED agent nearby**.
If false, a SUCEPTIBLE agent with INFECTED agents nearby will roll **only once, no matter how much infected agents are close.**
File added
from outputToGraph import run_java_jar, make_diagram, JAR_LOCATION,OUTPUT_FILE_LOCATION
import sys
import shutil
def save_csv(i) :
old_location = OUTPUT_FILE_LOCATION
new_location = f"src/main/resources/output{i}.csv"
shutil.move(old_location,new_location)
if ((len(sys.argv) > 1)):
for i in range (int(sys.argv[1])) :
run_java_jar(JAR_LOCATION)
make_diagram(OUTPUT_FILE_LOCATION)
save_csv(i)
else :
print("Usage : python3 multipleRuns.py <nb of runs>")
\ No newline at end of file
...@@ -53,7 +53,7 @@ def make_diagram(filename): ...@@ -53,7 +53,7 @@ def make_diagram(filename):
def run_java_jar(filename): def run_java_jar(filename):
import subprocess import subprocess
subprocess.call(['java', '-jar', filename]) subprocess.call(['java', '-jar',"--enable-preview", filename])
def copy_to_output_folder(filename): def copy_to_output_folder(filename):
...@@ -82,5 +82,6 @@ def edit_yaml(key, value): ...@@ -82,5 +82,6 @@ def edit_yaml(key, value):
# copyToOutputFolder(f"output{i}.csv") # copyToOutputFolder(f"output{i}.csv")
# makeDiagram(f"{OUTPUT_FOLDER}/output{i}.csv") # makeDiagram(f"{OUTPUT_FOLDER}/output{i}.csv")
run_java_jar(JAR_LOCATION) if __name__ == "__main__":
make_diagram(OUTPUT_FILE_LOCATION) run_java_jar(JAR_LOCATION)
make_diagram(OUTPUT_FILE_LOCATION)
...@@ -31,14 +31,14 @@ ...@@ -31,14 +31,14 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.13.2.2</version> <version>2.13.3</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml --> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId> <groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId> <artifactId>jackson-dataformat-yaml</artifactId>
<version>2.13.2</version> <version>2.13.3</version>
</dependency> </dependency>
</dependencies> </dependencies>
......
package agents; package agents;
import behaviors.Cyclic;
public sealed interface Agent public sealed interface Agent
permits CyclicAgent, ThreePhasedAgent{ permits CyclicAgent, ThreePhasedAgent{
......
...@@ -8,7 +8,7 @@ import java.awt.*; ...@@ -8,7 +8,7 @@ import java.awt.*;
public class RandomWalkingAgent3P extends RandomWakingAgent implements ThreePhasedSEIRSAgent { public class RandomWalkingAgent3P extends RandomWakingAgent implements ThreePhasedSEIRSAgent {
private String id; private final String id;
public RandomWalkingAgent3P(Point position, long seed, SEIRSEnvironment environment) { public RandomWalkingAgent3P(Point position, long seed, SEIRSEnvironment environment) {
super(position, seed, environment); super(position, seed, environment);
......
package agents.seirs; package agents.seirs;
import agents.CyclicAgent; import agents.CyclicAgent;
import agents.states.SEIRSState;
import behaviors.Infectious;
import behaviors.Positionable2D;
public interface CyclicSEIRSAgent extends CyclicAgent, SEIRSAgent { public interface CyclicSEIRSAgent extends CyclicAgent, SEIRSAgent {
......
...@@ -45,9 +45,13 @@ public abstract class FairInfectionRWAgent extends Randomized implements SEIRSAg ...@@ -45,9 +45,13 @@ public abstract class FairInfectionRWAgent extends Randomized implements SEIRSAg
@Override @Override
public boolean isExposed() { public boolean isExposed() {
return rollExposition(environment, position, r.nextInt(10000));
}
static boolean rollExposition(SEIRSEnvironment environment, Point position, int i2) {
boolean isExposed = false; boolean isExposed = false;
for (int i = 0 ; i<environment.getInfectedNeighbors(position).size() ; i++) { for (int i = 0; i< environment.getInfectedNeighbors(position).size() ; i++) {
int roll = r.nextInt(10000)+1; int roll = i2 +1;
if (roll <= YamlReader.getParams().infectionRate()*10000) { if (roll <= YamlReader.getParams().infectionRate()*10000) {
isExposed = true; isExposed = true;
} }
......
package agents.seirs; package agents.seirs;
import agents.ThreePhasedAgent;
import environment.SEIRSEnvironment; import environment.SEIRSEnvironment;
import java.awt.*; import java.awt.*;
public class FairInfectionRWAgent3P extends FairInfectionRWAgent implements ThreePhasedSEIRSAgent { public class FairInfectionRWAgent3P extends FairInfectionRWAgent implements ThreePhasedSEIRSAgent {
private String id; private final String id;
public FairInfectionRWAgent3P(Point position, long seed, SEIRSEnvironment environment) { public FairInfectionRWAgent3P(Point position, long seed, SEIRSEnvironment environment) {
super(position, seed, environment); super(position, seed, environment);
......
package agents.seirs; package agents.seirs;
import environment.SEIRSEnvironment; import environment.SEIRSEnvironment;
import utils.YamlReader;
import java.awt.*; import java.awt.*;
public class FairInfectionRWAgentCyclic extends FairInfectionRWAgent implements CyclicSEIRSAgent { public class FairInfectionRWAgentCyclic extends FairInfectionRWAgent implements CyclicSEIRSAgent {
private String id; private final String id;
public FairInfectionRWAgentCyclic(Point position, long seed, SEIRSEnvironment environment) { public FairInfectionRWAgentCyclic(Point position, long seed, SEIRSEnvironment environment) {
super(position, seed, environment); super(position, seed, environment);
this.id = String.valueOf(seed); this.id = String.valueOf(seed);
......
...@@ -9,6 +9,8 @@ import utils.YamlReader; ...@@ -9,6 +9,8 @@ import utils.YamlReader;
import java.awt.*; import java.awt.*;
import java.util.List; import java.util.List;
import static agents.seirs.FairInfectionRWAgent.rollExposition;
public abstract class RandomWakingAgent extends Randomized implements SEIRSAgent { public abstract class RandomWakingAgent extends Randomized implements SEIRSAgent {
protected Point position; protected Point position;
...@@ -46,14 +48,7 @@ public abstract class RandomWakingAgent extends Randomized implements SEIRSAgent ...@@ -46,14 +48,7 @@ public abstract class RandomWakingAgent extends Randomized implements SEIRSAgent
@Override @Override
public boolean isExposed() { public boolean isExposed() {
boolean isExposed = false; return rollExposition(environment, position, r.nextInt(10000));
for (int i = 0 ; i<environment.getInfectedNeighbors(position).size() ; i++) {
int roll = r.nextInt(10000)+1;
if (roll <= YamlReader.getParams().infectionRate()*10000) {
isExposed = true;
}
}
return isExposed;
} }
@Override @Override
......
package agents.seirs; package agents.seirs;
import agents.states.SEIRSState;
import agents.states.SuceptibleSEIRSState;
import behaviors.Randomized;
import environment.SEIRSEnvironment; import environment.SEIRSEnvironment;
import utils.YamlReader;
import java.awt.Point; import java.awt.Point;
import java.util.List;
public class RandomWalkingAgentCyclic extends RandomWakingAgent implements CyclicSEIRSAgent { public class RandomWalkingAgentCyclic extends RandomWakingAgent implements CyclicSEIRSAgent {
private String id; private final String id;
public RandomWalkingAgentCyclic(Point position, long seed, SEIRSEnvironment environment) { public RandomWalkingAgentCyclic(Point position, long seed, SEIRSEnvironment environment) {
super(position, seed, environment); super(position, seed, environment);
......
package agents.states; package agents.states;
import agents.seirs.CyclicSEIRSAgent;
import agents.seirs.SEIRSAgent; import agents.seirs.SEIRSAgent;
public class ExposedSEIRSState extends SEIRSState { public class ExposedSEIRSState extends SEIRSState {
......
package agents.states; package agents.states;
import agents.seirs.CyclicSEIRSAgent;
import agents.seirs.SEIRSAgent; import agents.seirs.SEIRSAgent;
public class InfectedSEIRSState extends SEIRSState { public class InfectedSEIRSState extends SEIRSState {
......
package agents.states; package agents.states;
import agents.seirs.CyclicSEIRSAgent;
import agents.seirs.SEIRSAgent; import agents.seirs.SEIRSAgent;
public class RecoveredSEIRSState extends SEIRSState { public class RecoveredSEIRSState extends SEIRSState {
......
package agents.states; package agents.states;
import agents.seirs.CyclicSEIRSAgent;
import agents.seirs.SEIRSAgent; import agents.seirs.SEIRSAgent;
public abstract class SEIRSState { public abstract class SEIRSState {
......
package agents.states; package agents.states;
import agents.seirs.CyclicSEIRSAgent;
import agents.seirs.SEIRSAgent; import agents.seirs.SEIRSAgent;
public class SuceptibleSEIRSState extends SEIRSState { public class SuceptibleSEIRSState extends SEIRSState {
...@@ -20,4 +19,10 @@ public class SuceptibleSEIRSState extends SEIRSState { ...@@ -20,4 +19,10 @@ public class SuceptibleSEIRSState extends SEIRSState {
public String toString() { public String toString() {
return SUCEPTIBLE; return SUCEPTIBLE;
} }
public static void main(String[] args) {
float i = 4.12f;
int i2 = (int) i;
System.out.println((float)i2);
}
} }
package environment; package environment;
import agents.Agent; import agents.Agent;
import agents.seirs.CyclicSEIRSAgent;
import agents.seirs.SEIRSAgent; import agents.seirs.SEIRSAgent;
import agents.states.InfectedSEIRSState; import agents.states.InfectedSEIRSState;
import agents.states.SEIRSState; import agents.states.SEIRSState;
...@@ -50,8 +49,8 @@ public class ChunkedSEIRSEnvironment implements SEIRSEnvironment { ...@@ -50,8 +49,8 @@ public class ChunkedSEIRSEnvironment implements SEIRSEnvironment {
private Point getRelativePoint(int relativeTo, Point p) { private Point getRelativePoint(int relativeTo, Point p) {
return switch (relativeTo) { return switch (relativeTo) {
case LEFT -> new Point(p.x-1,p.y); //case LEFT -> new Point(p.x-1,p.y);
case RIGHT -> new Point(p.x+1,p.y); case LEFT, RIGHT -> new Point(p.x+1,p.y);
case UP -> new Point(p.x,p.y-1); case UP -> new Point(p.x,p.y-1);
case DOWN -> new Point(p.x,p.y+1); case DOWN -> new Point(p.x,p.y+1);
case CENTER -> p; case CENTER -> p;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment