diff --git a/src/main/java/agents/RandomWalkingAgent.java b/src/main/java/agents/RandomWalkingAgent.java index 78cdd180cdfb5ea806ea99c23d52e5d171b295d9..6cc0bb889f7fc35293ebf60de74697574888a4a6 100644 --- a/src/main/java/agents/RandomWalkingAgent.java +++ b/src/main/java/agents/RandomWalkingAgent.java @@ -10,6 +10,7 @@ import java.security.SecureRandom; import java.util.List; import java.util.Random; +@SuppressWarnings("ThrowablePrintedToSystemOut") public class RandomWalkingAgent implements SEIRSAgent { protected Point position; @@ -19,10 +20,8 @@ public class RandomWalkingAgent implements SEIRSAgent { private List<Point> authorizedPositions; private Point nextPosition; - private int seed; public RandomWalkingAgent(Point position, int seed, SEIRSEnvironment environment) { - this.seed = seed; this.position = position; this.state = new SuceptibleSEIRSState(this); this.environment = environment; @@ -30,6 +29,7 @@ public class RandomWalkingAgent implements SEIRSAgent { r = SecureRandom.getInstance("SHA1PRNG", "SUN"); }catch (Exception e) { System.err.println(e); + System.exit(1); } r.setSeed(seed); } @@ -66,7 +66,7 @@ public class RandomWalkingAgent implements SEIRSAgent { boolean isExposed = false; for (int i = 0 ; i<environment.getInfectedNeighbors(position).size() ; i++) { int roll = r.nextInt(10000)+1; - if (roll <= YamlReader.getParams().getInfectionRate()*10000) { + if (roll <= YamlReader.getParams().infectionRate()*10000) { isExposed = true; } } @@ -77,7 +77,7 @@ public class RandomWalkingAgent implements SEIRSAgent { public boolean isInfected() { boolean isSick = false; int roll = r.nextInt(10000)+1; - if (roll <= YamlReader.getParams().getIncubationRate()*10000) { + if (roll <= YamlReader.getParams().incubationRate()*10000) { isSick = true; } return isSick; @@ -87,7 +87,7 @@ public class RandomWalkingAgent implements SEIRSAgent { public boolean isRecovered() { boolean isHealed = false; int roll = r.nextInt(10000)+1; - if (roll <= YamlReader.getParams().getRecoveryRate()*10000) { + if (roll <= YamlReader.getParams().recoveryRate()*10000) { isHealed = true; } return isHealed; @@ -97,7 +97,7 @@ public class RandomWalkingAgent implements SEIRSAgent { public boolean hasLostImmunity() { boolean hasLostImmunity = false; int roll = r.nextInt(10000)+1; - if (roll <= YamlReader.getParams().getLooseImmunityRate()*10000) { + if (roll <= YamlReader.getParams().looseImmunityRate()*10000) { hasLostImmunity = true; } return hasLostImmunity; diff --git a/src/main/java/environment/ChunkedSEIRSEnvironment.java b/src/main/java/environment/ChunkedSEIRSEnvironment.java index 685281fe130f0a7826be35e866ecef12dbdbc4e4..1bc7f5109c9ddd629d9ced94e129fa0cb6670740 100644 --- a/src/main/java/environment/ChunkedSEIRSEnvironment.java +++ b/src/main/java/environment/ChunkedSEIRSEnvironment.java @@ -78,32 +78,12 @@ public class ChunkedSEIRSEnvironment implements SEIRSEnvironment { return neighbors; } - private void wrapPosition(Point newPosition) { - if (newPosition.x >= size) { - newPosition.x -= size-1; - } - if (newPosition.x < 0) { - newPosition.x += size-1; - } - if (newPosition.y >= size) { - newPosition.y -= size-1; - } - if (newPosition.y < 0) { - newPosition.y +=size-1; - } - } - + @Override public List<Point> perceiveAuthorizedPositions(Agent2D agent) { List<Point> authorizedPosition = new ArrayList<>(); for (int move = 0; move < MAX_MOVEMENT; move++) { - Point position = switch (move) { - case LEFT -> new Point(agent.getPosition().x-RADIUS,agent.getPosition().y); - case RIGHT -> new Point (agent.getPosition().x+RADIUS,agent.getPosition().y); - case UP -> new Point(agent.getPosition().x, agent.getPosition().y-RADIUS); - case DOWN -> new Point(agent.getPosition().x, agent.getPosition().y +RADIUS); - default -> new Point(FORBIDDEN,FORBIDDEN); - }; + Point position = getNextPosition(move,agent.getPosition()); if (position.x < size && position.x >= 0 && position.y < size && position.y >= 0) { authorizedPosition.add(position); } @@ -111,6 +91,16 @@ public class ChunkedSEIRSEnvironment implements SEIRSEnvironment { return authorizedPosition; } + protected Point getNextPosition(int move, Point position) { + return switch (move) { + case LEFT -> new Point(position.x-RADIUS,position.y); + case RIGHT -> new Point (position.x+RADIUS,position.y); + case UP -> new Point(position.x, position.y-RADIUS); + case DOWN -> new Point(position.x, position.y +RADIUS); + default -> new Point(FORBIDDEN,FORBIDDEN); + }; + } + @Override public void notifyNewPosition(Point newPosition, Agent2D agent) { if (chunks == null) { @@ -121,7 +111,6 @@ public class ChunkedSEIRSEnvironment implements SEIRSEnvironment { chunks[oldPosition.x/CHUNK_SIZE][oldPosition.y/CHUNK_SIZE].remove((SEIRSAgent) agent); chunks[newPosition.x/CHUNK_SIZE][newPosition.y/CHUNK_SIZE].add((SEIRSAgent) agent); } - //wrapPosition(newPosition); } @Override diff --git a/src/main/java/environment/WrappingChunkedSEIRSEnvironment.java b/src/main/java/environment/WrappingChunkedSEIRSEnvironment.java new file mode 100644 index 0000000000000000000000000000000000000000..2ec979b1879510bb80ee28a937f8aa0ec2ca8e30 --- /dev/null +++ b/src/main/java/environment/WrappingChunkedSEIRSEnvironment.java @@ -0,0 +1,41 @@ +package environment; + +import agents.Agent2D; +import agents.SEIRSAgent; + +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +public class WrappingChunkedSEIRSEnvironment extends ChunkedSEIRSEnvironment implements SEIRSEnvironment{ + + public WrappingChunkedSEIRSEnvironment(int size, SEIRSAgent[] agents) { + super(size, agents); + } + + private void wrapPosition(Point newPosition) { + if (newPosition.x >= size) { + newPosition.x -= size-1; + } + if (newPosition.x < 0) { + newPosition.x += size-1; + } + if (newPosition.y >= size) { + newPosition.y -= size-1; + } + if (newPosition.y < 0) { + newPosition.y +=size-1; + } + } + + @Override + public List<Point> perceiveAuthorizedPositions(Agent2D agent) { + List<Point> authorisedPositions = new ArrayList<>(); + for (int move = 0; move < MAX_MOVEMENT; move++) { + Point position = getNextPosition(move,agent.getPosition()); + wrapPosition(position); + authorisedPositions.add(position); + } + return authorisedPositions; + } +} diff --git a/src/main/java/models/Parameters.java b/src/main/java/models/Parameters.java index f369c26da3eea937599b01276495f34a874f3f45..7c27d7c0f8a54b94b13ba999f965b504524c5cb0 100644 --- a/src/main/java/models/Parameters.java +++ b/src/main/java/models/Parameters.java @@ -1,74 +1,19 @@ package models; @SuppressWarnings("unused") -public class Parameters { - - private int seed; - private int population; - private int size; - private int nbOfPatientZero; - private float infectionRate; - private float incubationRate; - private float recoveryRate; - private float looseImmunityRate; - private int nbOfCycles; - private int timeBetweenCycles; - private boolean synchronousMode; - private boolean graphicalMode; - private boolean infectionStacks; - - public Parameters() { - } - - public int getNbOfPatientZero() {return nbOfPatientZero;} - - public void setNbOfPatientZero(int nbOfPatientZero) {this.nbOfPatientZero = nbOfPatientZero;} - - public int getSeed() {return seed;} - - public void setSeed(int seed) {this.seed = seed;} - - public int getPopulation() {return population;} - - public void setPopulation(int population) {this.population = population;} - - public int getSize() {return size;} - - public void setSize(int size) {this.size = size;} - - public float getInfectionRate() { return infectionRate; } - - public void setInfectionRate(float infectionRate) {this.infectionRate = infectionRate;} - - public float getIncubationRate() {return incubationRate;} - - public void setIncubationRate(float incubationRate) {this.incubationRate = incubationRate;} - - public float getRecoveryRate() {return recoveryRate;} - - public void setRecoveryRate(float recoveryRate) {this.recoveryRate = recoveryRate;} - - public float getLooseImmunityRate() { return looseImmunityRate; } - - public void setLooseImmunityRate(float looseImmunityRate) { this.looseImmunityRate = looseImmunityRate; } - - public int getNbOfCycles() {return nbOfCycles;} - - public void setNbOfCycles(int nbOfCycles) {this.nbOfCycles = nbOfCycles;} - - public boolean isSynchronousMode() {return synchronousMode;} - - public void setSynchronousMode(boolean synchronousMode) {this.synchronousMode = synchronousMode;} - - public int getTimeBetweenCycles() { return timeBetweenCycles; } - - public void setTimeBetweenCycles(int timeBetweenCycles) { this.timeBetweenCycles = timeBetweenCycles; } - - public boolean isGraphicalMode() { return graphicalMode; } - - public void setGraphicalMode(boolean graphicalMode) { this.graphicalMode = graphicalMode; } - - public boolean isInfectionStacks() { return infectionStacks; } - - public void setInfectionStacks(boolean infectionStacks) { this.infectionStacks = infectionStacks; } +public record Parameters( + int seed, + int population, + int size, + int nbOfPatientZero, + float infectionRate, + float incubationRate, + float recoveryRate, + float looseImmunityRate, + int nbOfCycles, + int timeBetweenCycles, + boolean synchronousMode, + boolean graphicalMode, + boolean infectionStacks, + boolean wrappingWorld) { } diff --git a/src/main/java/scheduler/FairSynchronousScheduler.java b/src/main/java/scheduler/FairSynchronousScheduler.java index e7bdd8726ec9f21b3e06ea02f5cb86ae95e0876e..50df63223cbd9d05efe917cd18010569c459dd12 100644 --- a/src/main/java/scheduler/FairSynchronousScheduler.java +++ b/src/main/java/scheduler/FairSynchronousScheduler.java @@ -2,10 +2,10 @@ package scheduler; import agents.Agent; -import java.nio.ByteBuffer; import java.security.SecureRandom; import java.util.*; +@SuppressWarnings("ThrowablePrintedToSystemOut") public class FairSynchronousScheduler implements Scheduler { private Agent[] agents; @@ -18,6 +18,7 @@ public class FairSynchronousScheduler implements Scheduler { r = SecureRandom.getInstance("SHA1PRNG", "SUN"); }catch (Exception e) { System.err.println(e); + System.exit(1); } r.setSeed(seed); } diff --git a/src/main/java/sma/SEIRS_SMA.java b/src/main/java/sma/SEIRS_SMA.java index d747d9e3dcdea40e17c9cd4c7d1c0898db6155df..ffd5778207418c3358b6483d1f11353e82b7e8eb 100644 --- a/src/main/java/sma/SEIRS_SMA.java +++ b/src/main/java/sma/SEIRS_SMA.java @@ -4,6 +4,7 @@ import agents.FairInfectionRWAgent; import agents.SEIRSAgent; import agents.states.InfectedSEIRSState; import environment.SEIRSEnvironment; +import environment.WrappingChunkedSEIRSEnvironment; import models.Parameters; import agents.RandomWalkingAgent; import environment.ChunkedSEIRSEnvironment; @@ -18,16 +19,13 @@ import view.StatisticsCanvas; import java.awt.*; import java.io.IOException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.time.Duration; import java.time.Instant; import java.util.Date; import java.util.HashMap; -import java.util.Random; -@SuppressWarnings("InfiniteLoopStatement") +@SuppressWarnings({"InfiniteLoopStatement", "ThrowablePrintedToSystemOut"}) public class SEIRS_SMA implements SMA{ private Parameters parameters; @@ -42,7 +40,7 @@ public class SEIRS_SMA implements SMA{ private HashMap<String,Integer> stats; private void initGraphics() { - statisticsCanvas = new StatisticsCanvas(300,parameters.getSize()); + statisticsCanvas = new StatisticsCanvas(300,parameters.size()); display = new DisplaySquaredEnvironment(environment,agents); fb.setSimulationCanvas(display); @@ -68,12 +66,12 @@ public class SEIRS_SMA implements SMA{ e.printStackTrace(); System.exit(1); } - if (parameters.isGraphicalMode()) { + if (parameters.graphicalMode()) { updateGraphics(); } - if (parameters.getTimeBetweenCycles() > 0) { + if (parameters.timeBetweenCycles() > 0) { try { - Thread.sleep(parameters.getTimeBetweenCycles()); + Thread.sleep(parameters.timeBetweenCycles()); } catch (InterruptedException e) { e.printStackTrace(); } @@ -81,38 +79,46 @@ public class SEIRS_SMA implements SMA{ } private void initPopulation() { - for (int i = 0; i<parameters.getPopulation();i++) { - Point position = new Point(r.nextInt(parameters.getSize()),r.nextInt(parameters.getSize())); + for (int i = 0; i<parameters.population();i++) { + Point position = new Point(r.nextInt(parameters.size()),r.nextInt(parameters.size())); SEIRSAgent agent; - if (parameters.isInfectionStacks()) { - agent = new RandomWalkingAgent(position,(parameters.getSeed()+i),environment); + if (parameters.infectionStacks()) { + agent = new RandomWalkingAgent(position,(parameters.seed()+i),environment); } else { - agent = new FairInfectionRWAgent(position,(parameters.getSeed()+i),environment); + agent = new FairInfectionRWAgent(position,(parameters.seed()+i),environment); } agents[i] = agent; } } private void infectPatientZero() { - for (int i=0 ; i< parameters.getNbOfPatientZero(); i++) { - int nextInt = (r.nextInt(parameters.getPopulation())); + for (int i=0 ; i< parameters.nbOfPatientZero(); i++) { + int nextInt = (r.nextInt(parameters.population())); SEIRSAgent agent = agents[nextInt]; while (agent.getState() instanceof InfectedSEIRSState) { - agent = agents[(r.nextInt(parameters.getPopulation()))]; + agent = agents[(r.nextInt(parameters.population()))]; } agent.changeState(new InfectedSEIRSState(agent)); } } private void initScheduler() { - if (parameters.isSynchronousMode()) { - scheduler = new FairSynchronousScheduler(parameters.getSeed()); + if (parameters.synchronousMode()) { + scheduler = new FairSynchronousScheduler(parameters.seed()); } else { scheduler = new FairAsynchronousScheduler(); } scheduler.init(agents); } + private void initEnvironment() { + if (parameters.wrappingWorld()) { + environment = new WrappingChunkedSEIRSEnvironment(parameters.size(),agents); + } else { + environment = new ChunkedSEIRSEnvironment(parameters.size(),agents); + } + } + @Override public void init() { @@ -121,14 +127,15 @@ public class SEIRS_SMA implements SMA{ r = SecureRandom.getInstance("SHA1PRNG", "SUN"); }catch (Exception e) { System.err.println(e); + System.exit(1); } - r.setSeed(parameters.getSeed()); - agents = new RandomWalkingAgent[parameters.getPopulation()]; - environment = new ChunkedSEIRSEnvironment(parameters.getSize(),agents); + r.setSeed(parameters.seed()); + agents = new RandomWalkingAgent[parameters.population()]; + initEnvironment(); initPopulation(); infectPatientZero(); initScheduler(); - if (parameters.isGraphicalMode()) { + if (parameters.graphicalMode()) { initGraphics(); } } @@ -138,13 +145,13 @@ public class SEIRS_SMA implements SMA{ public void run() { Instant startTime = Instant.now(); System.out.println("Starting simulation at : "+ Date.from(startTime)); - if (parameters.getNbOfCycles() <0) { + if (parameters.nbOfCycles() <0) { while (true) { doNextCycle(); } } else { int cpt = 0; - while (cpt < parameters.getNbOfCycles()) { + while (cpt < parameters.nbOfCycles()) { doNextCycle(); cpt++; } diff --git a/src/main/resources/output.png b/src/main/resources/output.png index e7519955ea48feef9451aeeff9c5f41088f39f69..3ed5fabfa0eedf57027acae44ace198dfc976a4d 100644 Binary files a/src/main/resources/output.png and b/src/main/resources/output.png differ diff --git a/src/main/resources/parameters.yaml b/src/main/resources/parameters.yaml index 7550017412ecc4a8acc98c8631f4a0b6c15c8820..a7e09b7db38122e90ac2ae1889043a78d7187e6a 100644 --- a/src/main/resources/parameters.yaml +++ b/src/main/resources/parameters.yaml @@ -1,6 +1,6 @@ graphicalMode: true incubationRate: 0.3 -infectionRate: 1 +infectionRate: 0.8 looseImmunityRate: 0.008 recoveryRate: 0.1429 nbOfCycles: 2000 @@ -8,6 +8,7 @@ nbOfPatientZero: 1 population: 3000 seed: 120 size: 1000 +wrappingWorld : true synchronousMode: false -timeBetweenCycles: 10 +timeBetweenCycles: 0 infectionStacks : true \ No newline at end of file