diff --git a/.idea/misc.xml b/.idea/misc.xml index b37905cbee66b9e11bfc56f34e4576f2109fe859..2e4f09532a98163d74355d8086d519b2ff1de9a7 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,15 +11,10 @@ </list> </option> </component> - <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK"> + <component name="ProjectRootManager" version="2" languageLevel="JDK_18" default="true" project-jdk-name="17" project-jdk-type="JavaSDK"> <output url="file://$PROJECT_DIR$/out" /> </component> <component name="ProjectType"> <option name="id" value="jpab" /> </component> - <component name="SwUserDefinedSpecifications"> - <option name="specTypeByUrl"> - <map /> - </option> - </component> </project> \ No newline at end of file diff --git a/pom.xml b/pom.xml index f99378b8c9207485fbfb01e82c8b4ffd38c84e37..28e3de1e62dd55223da8bee198c9132cc761bdfe 100644 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,19 @@ <groupId>org.IRIT</groupId> <artifactId>SMA-SEIR</artifactId> <version>0.1</version> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>18</source> + <target>18</target> + <compilerArgs>--enable-preview</compilerArgs> + </configuration> + </plugin> + </plugins> + </build> <properties> <maven.compiler.source>17</maven.compiler.source> diff --git a/src/main/java/agents/Agent.java b/src/main/java/agents/Agent.java index 56c1ada9e0d1ac205ab52a890a8f41ae670965b1..c4b9c12ddbcf33182028b28f270a63ec16e3b278 100644 --- a/src/main/java/agents/Agent.java +++ b/src/main/java/agents/Agent.java @@ -1,8 +1,9 @@ package agents; -import behaviors.Wakeable; +import behaviors.Cyclic; -public interface Agent extends Wakeable { +public sealed interface Agent +permits CyclicAgent, ThreePhasedAgent{ String getId(); } diff --git a/src/main/java/agents/CyclicAgent.java b/src/main/java/agents/CyclicAgent.java new file mode 100644 index 0000000000000000000000000000000000000000..5c6649d8ea095d5ac06cd219ea82412bb21003c2 --- /dev/null +++ b/src/main/java/agents/CyclicAgent.java @@ -0,0 +1,6 @@ +package agents; + +import behaviors.Cyclic; + +public non-sealed interface CyclicAgent extends Agent, Cyclic { +} diff --git a/src/main/java/agents/FairInfectionRWAgent.java b/src/main/java/agents/FairInfectionRWAgent.java deleted file mode 100644 index 260525253a5526bf4676b742573dfce8e9a9832e..0000000000000000000000000000000000000000 --- a/src/main/java/agents/FairInfectionRWAgent.java +++ /dev/null @@ -1,25 +0,0 @@ -package agents; - -import environment.SEIRSEnvironment; -import utils.YamlReader; - -import java.awt.*; - -public class FairInfectionRWAgent extends RandomWalkingAgent implements SEIRSAgent { - - public FairInfectionRWAgent(Point position, long seed, SEIRSEnvironment environment) { - super(position, seed, environment); - } - - @Override - public boolean isExposed() { - boolean isExposed = false; - int roll = r.nextInt(10000)+1; - if (this.environment.getInfectedNeighbors(position).size() != 0) { - if (roll <= YamlReader.getParams().infectionRate()*10000) { - isExposed = true; - } - } - return isExposed; - } -} diff --git a/src/main/java/agents/RandomWalkingAgent3P.java b/src/main/java/agents/RandomWalkingAgent3P.java new file mode 100644 index 0000000000000000000000000000000000000000..7edbcae221f05cc1e16523883015f7263383d016 --- /dev/null +++ b/src/main/java/agents/RandomWalkingAgent3P.java @@ -0,0 +1,37 @@ +package agents; + +import agents.seirs.RandomWakingAgent; +import agents.seirs.ThreePhasedSEIRSAgent; +import environment.SEIRSEnvironment; + +import java.awt.*; + +public class RandomWalkingAgent3P extends RandomWakingAgent implements ThreePhasedSEIRSAgent { + + private String id; + + public RandomWalkingAgent3P(Point position, long seed, SEIRSEnvironment environment) { + super(position, seed, environment); + this.id = String.valueOf(seed); + } + + @Override + public String getId() { + return id; + } + + @Override + public void perceive() { + perceiveAuthorizedPositions(); + } + + @Override + public void decide() { + decideNextMove(); + } + + @Override + public void act() { + move(); + } +} diff --git a/src/main/java/agents/ThreePhasedAgent.java b/src/main/java/agents/ThreePhasedAgent.java new file mode 100644 index 0000000000000000000000000000000000000000..3c4c91bd474fb1f59a56c9f40e98ea2e53147dc3 --- /dev/null +++ b/src/main/java/agents/ThreePhasedAgent.java @@ -0,0 +1,7 @@ +package agents; + +import behaviors.ThreePhased; + +public non-sealed interface ThreePhasedAgent extends Agent, ThreePhased { + +} diff --git a/src/main/java/agents/seirs/CyclicSEIRSAgent.java b/src/main/java/agents/seirs/CyclicSEIRSAgent.java new file mode 100644 index 0000000000000000000000000000000000000000..135b9f805acd4d660bff23a909a819d5d7e9198c --- /dev/null +++ b/src/main/java/agents/seirs/CyclicSEIRSAgent.java @@ -0,0 +1,11 @@ +package agents.seirs; + +import agents.CyclicAgent; +import agents.states.SEIRSState; +import behaviors.Infectious; +import behaviors.Positionable2D; + +public interface CyclicSEIRSAgent extends CyclicAgent, SEIRSAgent { + + void wakeUp(); +} diff --git a/src/main/java/agents/seirs/FairInfectionRWAgent.java b/src/main/java/agents/seirs/FairInfectionRWAgent.java new file mode 100644 index 0000000000000000000000000000000000000000..2aebf28e8763a562f185ed36e88a1fa2e40236c2 --- /dev/null +++ b/src/main/java/agents/seirs/FairInfectionRWAgent.java @@ -0,0 +1,93 @@ +package agents.seirs; + +import agents.states.SEIRSState; +import agents.states.SuceptibleSEIRSState; +import behaviors.Randomized; +import environment.SEIRSEnvironment; +import utils.YamlReader; + +import java.awt.*; +import java.util.List; + +public abstract class FairInfectionRWAgent extends Randomized implements SEIRSAgent { + + protected Point position; + protected final SEIRSEnvironment environment; + protected SEIRSState state; + + protected List<Point> authorizedPositions; + protected Point nextPosition; + public FairInfectionRWAgent(Point position, long seed, SEIRSEnvironment environment) { + super(seed); + this.position = position; + this.state = new SuceptibleSEIRSState(this); + this.environment = environment; + r.setSeed(seed); + } + + protected void move() { + state.onMovement(); + environment.notifyNewPosition(nextPosition,this); + position = nextPosition; + } + + protected void perceiveAuthorizedPositions() { + authorizedPositions = environment.perceiveAuthorizedPositions(this); + } + + protected void decideNextMove() { + int next = r.nextInt(authorizedPositions.size()); + nextPosition = authorizedPositions.get(next); + } + + @Override + public void changeState(SEIRSState SEIRSState) { this.state = SEIRSState; } + + @Override + public boolean isExposed() { + boolean isExposed = false; + 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 + public boolean isInfected() { + boolean isSick = false; + int roll = r.nextInt(10000)+1; + if (roll <= YamlReader.getParams().incubationRate()*10000) { + isSick = true; + } + return isSick; + } + + @Override + public boolean isRecovered() { + boolean isHealed = false; + int roll = r.nextInt(10000)+1; + if (roll <= YamlReader.getParams().recoveryRate()*10000) { + isHealed = true; + } + return isHealed; + } + + @Override + public boolean hasLostImmunity() { + boolean hasLostImmunity = false; + int roll = r.nextInt(10000)+1; + if (roll <= YamlReader.getParams().looseImmunityRate()*10000) { + hasLostImmunity = true; + } + return hasLostImmunity; + } + + @Override + public SEIRSState getState() { return this.state; } + + @Override + public Point getPosition() { return position; } +} diff --git a/src/main/java/agents/seirs/FairInfectionRWAgent3P.java b/src/main/java/agents/seirs/FairInfectionRWAgent3P.java new file mode 100644 index 0000000000000000000000000000000000000000..e69c6fd026325cdf7f6a1afc486ee99a3997d5d3 --- /dev/null +++ b/src/main/java/agents/seirs/FairInfectionRWAgent3P.java @@ -0,0 +1,36 @@ +package agents.seirs; + +import agents.ThreePhasedAgent; +import environment.SEIRSEnvironment; + +import java.awt.*; + +public class FairInfectionRWAgent3P extends FairInfectionRWAgent implements ThreePhasedSEIRSAgent { + + private String id; + + public FairInfectionRWAgent3P(Point position, long seed, SEIRSEnvironment environment) { + super(position, seed, environment); + this.id = String.valueOf(seed); + } + + @Override + public void perceive() { + perceiveAuthorizedPositions(); + } + + @Override + public void decide() { + decideNextMove(); + } + + @Override + public void act() { + move(); + } + + @Override + public String getId() { + return this.id; + } +} diff --git a/src/main/java/agents/seirs/FairInfectionRWAgentCyclic.java b/src/main/java/agents/seirs/FairInfectionRWAgentCyclic.java new file mode 100644 index 0000000000000000000000000000000000000000..707f1d7505b3e92758c7b75e166b42ef76e25538 --- /dev/null +++ b/src/main/java/agents/seirs/FairInfectionRWAgentCyclic.java @@ -0,0 +1,29 @@ +package agents.seirs; + +import environment.SEIRSEnvironment; +import utils.YamlReader; + +import java.awt.*; + +public class FairInfectionRWAgentCyclic extends FairInfectionRWAgent implements CyclicSEIRSAgent { + + private String id; + public FairInfectionRWAgentCyclic(Point position, long seed, SEIRSEnvironment environment) { + super(position, seed, environment); + this.id = String.valueOf(seed); + } + + @Override + public void wakeUp() { + perceiveAuthorizedPositions(); + if (!authorizedPositions.isEmpty()) { + decideNextMove(); + move(); + } + } + @Override + public String getId() { + return this.id; + } + +} diff --git a/src/main/java/agents/RandomWalkingAgent.java b/src/main/java/agents/seirs/RandomWakingAgent.java similarity index 75% rename from src/main/java/agents/RandomWalkingAgent.java rename to src/main/java/agents/seirs/RandomWakingAgent.java index c14ce90a6750ec138bda72a8be950264a203d79d..bccdf5d4a69f0a291829689afeaaf1ad9a9403ef 100644 --- a/src/main/java/agents/RandomWalkingAgent.java +++ b/src/main/java/agents/seirs/RandomWakingAgent.java @@ -1,4 +1,4 @@ -package agents; +package agents.seirs; import agents.states.SEIRSState; import agents.states.SuceptibleSEIRSState; @@ -6,52 +6,41 @@ import behaviors.Randomized; import environment.SEIRSEnvironment; import utils.YamlReader; -import java.awt.Point; +import java.awt.*; import java.util.List; -public class RandomWalkingAgent extends Randomized implements SEIRSAgent { +public abstract class RandomWakingAgent extends Randomized implements SEIRSAgent { protected Point position; protected final SEIRSEnvironment environment; protected SEIRSState state; - private List<Point> authorizedPositions; - private Point nextPosition; - private final String id; + protected List<Point> authorizedPositions; + protected Point nextPosition; - public RandomWalkingAgent(Point position, long seed, SEIRSEnvironment environment) { + public RandomWakingAgent(Point position, long seed, SEIRSEnvironment environment) { super(seed); - this.id = String.valueOf(seed); this.position = position; this.state = new SuceptibleSEIRSState(this); this.environment = environment; r.setSeed(seed); } - private void move() { + protected void move() { state.onMovement(); environment.notifyNewPosition(nextPosition,this); position = nextPosition; } - private void perceiveAuthorizedPositions() { + protected void perceiveAuthorizedPositions() { authorizedPositions = environment.perceiveAuthorizedPositions(this); } - private void decideNextMove() { + protected void decideNextMove() { int next = r.nextInt(authorizedPositions.size()); nextPosition = authorizedPositions.get(next); } - @Override - public void wakeUp() { - perceiveAuthorizedPositions(); - if (!authorizedPositions.isEmpty()) { - decideNextMove(); - move(); - } - } - @Override public void changeState(SEIRSState SEIRSState) { this.state = SEIRSState; } @@ -103,9 +92,4 @@ public class RandomWalkingAgent extends Randomized implements SEIRSAgent { @Override public Point getPosition() { return position; } - @Override - public String getId() { - return this.id; - } - } diff --git a/src/main/java/agents/seirs/RandomWalkingAgentCyclic.java b/src/main/java/agents/seirs/RandomWalkingAgentCyclic.java new file mode 100644 index 0000000000000000000000000000000000000000..6c1874cb898ea5f04b76ab3edbee1d19339d9b89 --- /dev/null +++ b/src/main/java/agents/seirs/RandomWalkingAgentCyclic.java @@ -0,0 +1,34 @@ +package agents.seirs; + +import agents.states.SEIRSState; +import agents.states.SuceptibleSEIRSState; +import behaviors.Randomized; +import environment.SEIRSEnvironment; +import utils.YamlReader; + +import java.awt.Point; +import java.util.List; + +public class RandomWalkingAgentCyclic extends RandomWakingAgent implements CyclicSEIRSAgent { + + private String id; + + public RandomWalkingAgentCyclic(Point position, long seed, SEIRSEnvironment environment) { + super(position, seed, environment); + this.id = String.valueOf(seed); + } + + @Override + public void wakeUp() { + perceiveAuthorizedPositions(); + if (!authorizedPositions.isEmpty()) { + decideNextMove(); + move(); + } + } + @Override + public String getId() { + return this.id; + } + +} diff --git a/src/main/java/agents/seirs/SEIRSAgent.java b/src/main/java/agents/seirs/SEIRSAgent.java new file mode 100644 index 0000000000000000000000000000000000000000..fb8244fbb2b94620fe9631da0e8ec571c403471a --- /dev/null +++ b/src/main/java/agents/seirs/SEIRSAgent.java @@ -0,0 +1,7 @@ +package agents.seirs; + +import behaviors.Infectious; +import behaviors.Positionable2D; + +public interface SEIRSAgent extends Positionable2D, Infectious { +} diff --git a/src/main/java/agents/seirs/ThreePhasedSEIRSAgent.java b/src/main/java/agents/seirs/ThreePhasedSEIRSAgent.java new file mode 100644 index 0000000000000000000000000000000000000000..019fa3444c14c18d7bc4dd2340eb96136016b11d --- /dev/null +++ b/src/main/java/agents/seirs/ThreePhasedSEIRSAgent.java @@ -0,0 +1,7 @@ +package agents.seirs; + +import agents.ThreePhasedAgent; + +public interface ThreePhasedSEIRSAgent extends ThreePhasedAgent,SEIRSAgent { + +} diff --git a/src/main/java/agents/states/ExposedSEIRSState.java b/src/main/java/agents/states/ExposedSEIRSState.java index c7dbbcccad4c9c9764732ab5a821a308d9469ea2..b24651c0247761252d9589d5ebbc21ce66aad8f2 100644 --- a/src/main/java/agents/states/ExposedSEIRSState.java +++ b/src/main/java/agents/states/ExposedSEIRSState.java @@ -1,6 +1,7 @@ package agents.states; -import agents.SEIRSAgent; +import agents.seirs.CyclicSEIRSAgent; +import agents.seirs.SEIRSAgent; public class ExposedSEIRSState extends SEIRSState { diff --git a/src/main/java/agents/states/InfectedSEIRSState.java b/src/main/java/agents/states/InfectedSEIRSState.java index 012d0cb8dfd7cba0cd3a5f337cfa24f80f56563c..d8c18f291b233e4aa8c109cf15ec1341fc9234d7 100644 --- a/src/main/java/agents/states/InfectedSEIRSState.java +++ b/src/main/java/agents/states/InfectedSEIRSState.java @@ -1,6 +1,7 @@ package agents.states; -import agents.SEIRSAgent; +import agents.seirs.CyclicSEIRSAgent; +import agents.seirs.SEIRSAgent; public class InfectedSEIRSState extends SEIRSState { diff --git a/src/main/java/agents/states/RecoveredSEIRSState.java b/src/main/java/agents/states/RecoveredSEIRSState.java index 11df581e4c827d540adfef5f1e915318101a281a..0a05430d3368b05fc059ac3cfa3b70597a7fcbbc 100644 --- a/src/main/java/agents/states/RecoveredSEIRSState.java +++ b/src/main/java/agents/states/RecoveredSEIRSState.java @@ -1,6 +1,7 @@ package agents.states; -import agents.SEIRSAgent; +import agents.seirs.CyclicSEIRSAgent; +import agents.seirs.SEIRSAgent; public class RecoveredSEIRSState extends SEIRSState { diff --git a/src/main/java/agents/states/SEIRSState.java b/src/main/java/agents/states/SEIRSState.java index 78725a4808b0ff3541a126aee59485e4f61758a2..966453fa1ab5a0aa596474a32a48cb4ac560e163 100644 --- a/src/main/java/agents/states/SEIRSState.java +++ b/src/main/java/agents/states/SEIRSState.java @@ -1,6 +1,7 @@ package agents.states; -import agents.SEIRSAgent; +import agents.seirs.CyclicSEIRSAgent; +import agents.seirs.SEIRSAgent; public abstract class SEIRSState { @@ -9,7 +10,7 @@ public abstract class SEIRSState { public final static String SUCEPTIBLE = "SUCEPTIBLE"; public final static String RECOVERED = "RECOVERED"; - protected final agents.SEIRSAgent agent; + protected final SEIRSAgent agent; SEIRSState(SEIRSAgent agent) { this.agent = agent; diff --git a/src/main/java/agents/states/SuceptibleSEIRSState.java b/src/main/java/agents/states/SuceptibleSEIRSState.java index 28a2511c078bfc66dda80ecdeca91da72e036178..87c5335c6ef7ce42db23d6c454eb79de17119887 100644 --- a/src/main/java/agents/states/SuceptibleSEIRSState.java +++ b/src/main/java/agents/states/SuceptibleSEIRSState.java @@ -1,6 +1,7 @@ package agents.states; -import agents.SEIRSAgent; +import agents.seirs.CyclicSEIRSAgent; +import agents.seirs.SEIRSAgent; public class SuceptibleSEIRSState extends SEIRSState { diff --git a/src/main/java/behaviors/Wakeable.java b/src/main/java/behaviors/Cyclic.java similarity index 58% rename from src/main/java/behaviors/Wakeable.java rename to src/main/java/behaviors/Cyclic.java index dfb18696f438cbcecbdf1413030aecf10bb1fe07..9b6d789f047a8e75f67cdb66be4336c758dbead9 100644 --- a/src/main/java/behaviors/Wakeable.java +++ b/src/main/java/behaviors/Cyclic.java @@ -1,5 +1,5 @@ package behaviors; -public interface Wakeable { +public interface Cyclic { void wakeUp(); } \ No newline at end of file diff --git a/src/main/java/agents/SEIRSAgent.java b/src/main/java/behaviors/Infectious.java similarity index 66% rename from src/main/java/agents/SEIRSAgent.java rename to src/main/java/behaviors/Infectious.java index 1a5242fb9e7a87aeb97ff3fc4c3ebe57ad167ac5..e16f7000ab682bef5911e3b4acab11534f3078f8 100644 --- a/src/main/java/agents/SEIRSAgent.java +++ b/src/main/java/behaviors/Infectious.java @@ -1,10 +1,8 @@ -package agents; +package behaviors; import agents.states.SEIRSState; -import behaviors.Positionable2D; - -public interface SEIRSAgent extends Agent, Positionable2D { +public interface Infectious { void changeState(SEIRSState SEIRSState); SEIRSState getState(); boolean isExposed(); diff --git a/src/main/java/behaviors/ThreePhased.java b/src/main/java/behaviors/ThreePhased.java new file mode 100644 index 0000000000000000000000000000000000000000..c077b09e63b7877f9e2bbd2bc07dbacd54bd4343 --- /dev/null +++ b/src/main/java/behaviors/ThreePhased.java @@ -0,0 +1,9 @@ +package behaviors; + +public interface ThreePhased { + + void perceive(); + void decide(); + void act(); + +} diff --git a/src/main/java/environment/ChunkedSEIRSEnvironment.java b/src/main/java/environment/ChunkedSEIRSEnvironment.java index e754588c510bf08394ae55fc599747f6881aa4f4..d489eac3482fc4e1bd0d438eee72d14a0aa8e983 100644 --- a/src/main/java/environment/ChunkedSEIRSEnvironment.java +++ b/src/main/java/environment/ChunkedSEIRSEnvironment.java @@ -1,6 +1,8 @@ package environment; -import agents.SEIRSAgent; +import agents.Agent; +import agents.seirs.CyclicSEIRSAgent; +import agents.seirs.SEIRSAgent; import agents.states.InfectedSEIRSState; import agents.states.SEIRSState; import behaviors.Positionable2D; @@ -112,7 +114,7 @@ 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); } - executionOrder.add(((SEIRSAgent)agent).getId()); + executionOrder.add(((Agent)agent).getId()); } @Override @@ -139,8 +141,8 @@ public class ChunkedSEIRSEnvironment implements SEIRSEnvironment { map.put(SEIRSState.RECOVERED,0); map.put(SEIRSState.SUCEPTIBLE,0); - for (SEIRSAgent SEIRSAgent : agents) { - String state = SEIRSAgent.getState().toString(); + for (SEIRSAgent agent : agents) { + String state = agent.getState().toString(); map.put(state,map.get(state)+1); } return map; diff --git a/src/main/java/environment/SEIRSEnvironment.java b/src/main/java/environment/SEIRSEnvironment.java index ddd65494ce7a40a8f0d40de8f5b3a17b3cf999ff..7e2a804885d784ac46aed87fea5b3d118c12639e 100644 --- a/src/main/java/environment/SEIRSEnvironment.java +++ b/src/main/java/environment/SEIRSEnvironment.java @@ -1,6 +1,7 @@ package environment; -import agents.SEIRSAgent; +import agents.seirs.CyclicSEIRSAgent; +import agents.seirs.SEIRSAgent; import java.awt.*; import java.util.HashMap; diff --git a/src/main/java/environment/WrappingChunkedSEIRSEnvironment.java b/src/main/java/environment/WrappingChunkedSEIRSEnvironment.java index 4cfaa5271aa06c9edbfb3d4374b9c9802839091b..024638e8d46adcaf775118cb6b8005abb5ea79f4 100644 --- a/src/main/java/environment/WrappingChunkedSEIRSEnvironment.java +++ b/src/main/java/environment/WrappingChunkedSEIRSEnvironment.java @@ -1,6 +1,7 @@ package environment; -import agents.SEIRSAgent; +import agents.seirs.CyclicSEIRSAgent; +import agents.seirs.SEIRSAgent; import behaviors.Positionable2D; import java.awt.*; diff --git a/src/main/java/models/Parameters.java b/src/main/java/models/Parameters.java index 6ff1c2ea0910a6553468e72c3e553eeaa394b35f..5806c241fe26aa964bbf53b52a27a6e083987270 100644 --- a/src/main/java/models/Parameters.java +++ b/src/main/java/models/Parameters.java @@ -17,5 +17,6 @@ public record Parameters( boolean infectionStacks, boolean wrappingWorld, boolean playRecord, - boolean recordExperiment) { + boolean recordExperiment, + boolean threePhased) { } diff --git a/src/main/java/scheduler/DeterministScheduler.java b/src/main/java/scheduler/DeterministScheduler.java index 0c243e9b5651516e7ce06a8e29b800c56d622451..e712d7bb58d242f90f0139f0ae6d33957b0872b6 100644 --- a/src/main/java/scheduler/DeterministScheduler.java +++ b/src/main/java/scheduler/DeterministScheduler.java @@ -1,6 +1,8 @@ package scheduler; -import behaviors.Wakeable; +import agents.Agent; +import agents.CyclicAgent; +import agents.ThreePhasedAgent; import utils.YamlReader; import java.io.BufferedReader; @@ -8,11 +10,14 @@ import java.io.FileReader; import java.io.IOException; import java.util.*; +@SuppressWarnings("ConstantConditions") public class DeterministScheduler implements Scheduler { - private Wakeable[] agents; + private Agent[] agents; private final Queue<String> wakeUpOrder = new LinkedList<>(); + private Boolean isThreePhased; + public DeterministScheduler(String csvFile) { readCSV(csvFile); } @@ -28,12 +33,15 @@ public class DeterministScheduler implements Scheduler { } @Override - public void init(Wakeable[] agents) { + public void init(Agent[] agents) { + isThreePhased = switch (agents[0]) { + case ThreePhasedAgent ignored -> true; + case CyclicAgent ignored -> false; + }; this.agents = agents; } - @Override - public void doNextCycle() { + private void wakeUpNextCycle(CyclicAgent[] agents) { for (int i = 0 ; i<agents.length; i++) { try { int next = Integer.parseInt(wakeUpOrder.poll()); @@ -44,4 +52,49 @@ public class DeterministScheduler implements Scheduler { } } } + + private void perceiveNextCycle(ThreePhasedAgent[] agents, List<Integer> nextCycle) { + for (Integer i : nextCycle) { + agents[i].perceive(); + } + } + + private void decideNextCycle(ThreePhasedAgent[] agents, List<Integer> nextCycle) { + for (Integer i : nextCycle) { + agents[i].decide(); + } + } + + private void actNextCycle(ThreePhasedAgent[] agents, List<Integer> nextCycle) { + for (Integer i : nextCycle) { + agents[i].act(); + } + } + + private List<Integer> getNextCycle() { + List<Integer> nextCycle = new ArrayList<>(); + for (int i = 0 ; i<agents.length; i++ ) { + try { + nextCycle.add(Integer.parseInt(wakeUpOrder.poll())); + } catch (EmptyStackException e) { + System.err.println("Last record entry was read, simulation cannot continue further."); + System.exit(1); + } + } + return nextCycle; + } + + @Override + public void doNextCycle() { + if (isThreePhased) { + List<Integer> nextCycle = getNextCycle(); + ThreePhasedAgent[] agents = (ThreePhasedAgent[])this.agents; + perceiveNextCycle(agents,nextCycle); + decideNextCycle(agents,nextCycle); + actNextCycle(agents,nextCycle); + } else { + CyclicAgent[] agents = (CyclicAgent[]) this.agents; + wakeUpNextCycle(agents); + } + } } diff --git a/src/main/java/scheduler/FairAsynchronousScheduler.java b/src/main/java/scheduler/FairAsynchronousScheduler.java index de564d945497d27fe3702b08999b4dfa4c8d18b7..634d564f93cdc24758d251908123ec60de7db342 100644 --- a/src/main/java/scheduler/FairAsynchronousScheduler.java +++ b/src/main/java/scheduler/FairAsynchronousScheduler.java @@ -1,6 +1,8 @@ package scheduler; -import behaviors.Wakeable; +import agents.Agent; +import agents.CyclicAgent; +import agents.ThreePhasedAgent; import java.util.Arrays; import java.util.List; @@ -12,17 +14,35 @@ import java.util.stream.Collectors; public class FairAsynchronousScheduler implements Scheduler { private final ExecutorService executor = Executors.newSingleThreadExecutor(); - private Queue<Wakeable> queue; + private Queue<Agent> queue; + + private Boolean isThreePhased; @Override - public void init(Wakeable[] agents) { + public void init(Agent[] agents) { this.queue = new ConcurrentLinkedQueue<>(Arrays.stream(agents).toList()); + isThreePhased = switch (agents[0]) { + case ThreePhasedAgent ignored -> true; + case CyclicAgent ignored -> false; + }; } - @Override - public void doNextCycle() { - List<Future<Wakeable>> results = queue.parallelStream().map(entity -> executor.submit(() -> {entity.wakeUp(); return entity;})).toList(); - Function<Future<Wakeable>, Wakeable> futureTreatment = futureEntity -> { + private void wakeAll() { + List<Future<Agent>> results = queue.parallelStream() + .map(entity -> executor.submit(() -> { + ((CyclicAgent)entity).wakeUp(); return entity;})).toList(); + getFutureAgents(results); + } + + private void perceiveAll() { + List<Future<Agent>> results = queue.parallelStream() + .map(entity -> executor.submit(() -> { + ((ThreePhasedAgent)entity).perceive(); return entity;})).toList(); + getFutureAgents(results); + } + + private void getFutureAgents(List<Future<Agent>> results) { + Function<Future<Agent>, Agent> futureTreatment = futureEntity -> { try { return futureEntity.get(); } catch (ExecutionException | InterruptedException e) { @@ -32,4 +52,29 @@ public class FairAsynchronousScheduler implements Scheduler { }; queue = results.parallelStream().map(futureTreatment).collect(Collectors.toCollection(ConcurrentLinkedQueue::new)); } + + private void decideAll() { + List<Future<Agent>> results = queue.parallelStream() + .map(entity -> executor.submit(() -> { + ((ThreePhasedAgent)entity).decide(); return entity;})).toList(); + getFutureAgents(results); + } + + private void actAll() { + List<Future<Agent>> results = queue.parallelStream() + .map(entity -> executor.submit(() -> { + ((ThreePhasedAgent)entity).act(); return entity;})).toList(); + getFutureAgents(results); + } + + @Override + public void doNextCycle() { + if (isThreePhased) { + perceiveAll(); + decideAll(); + actAll(); + } else { + wakeAll(); + } + } } diff --git a/src/main/java/scheduler/FairSynchronousScheduler.java b/src/main/java/scheduler/FairSynchronousScheduler.java index b99e892d8b33f23f3c5f992b35e92e1f70613652..7c540a2f86c4df0f0c84c35d997d4f43d38e869d 100644 --- a/src/main/java/scheduler/FairSynchronousScheduler.java +++ b/src/main/java/scheduler/FairSynchronousScheduler.java @@ -1,15 +1,19 @@ package scheduler; +import agents.Agent; +import agents.CyclicAgent; +import agents.ThreePhasedAgent; import behaviors.Randomized; -import behaviors.Wakeable; import java.util.*; public class FairSynchronousScheduler extends Randomized implements Scheduler { - private Wakeable[] agents; + private Agent[] agents; private Stack<Integer> executionOrder; + private Boolean isThreePhased; + public FairSynchronousScheduler(long seed) { super(seed); } @@ -21,15 +25,38 @@ public class FairSynchronousScheduler extends Randomized implements Scheduler { Collections.shuffle(executionOrder,r); } - private void wakeAgents() { + private void wakeAgents(CyclicAgent[] agents) { while (!executionOrder.isEmpty()) { - agents[(executionOrder.pop())].wakeUp(); + (agents[(executionOrder.pop())]).wakeUp(); + + } + } + private void perceiveAll(ThreePhasedAgent[] agents) { + for (Integer next : executionOrder) { + agents[next].perceive(); } } + private void decideAll(ThreePhasedAgent[] agents) { + for (Integer next : executionOrder) { + agents[next].decide(); + } + } + + private void actAll(ThreePhasedAgent[] agents) { + for (Integer next : executionOrder) { + agents[next].act(); + } + executionOrder.clear(); + } + @Override - public void init(Wakeable[] agents) { + public void init(Agent[] agents) { + isThreePhased = switch (agents[0]) { + case CyclicAgent ignored -> false; + case ThreePhasedAgent ignored -> true; + }; this.agents = agents; executionOrder = new Stack<>(); } @@ -37,6 +64,14 @@ public class FairSynchronousScheduler extends Randomized implements Scheduler { @Override public void doNextCycle() { generateExecutionOrder(); - wakeAgents(); + if (isThreePhased) { + ThreePhasedAgent[] agents = (ThreePhasedAgent[])this.agents; + perceiveAll(agents); + decideAll(agents); + actAll(agents); + }else { + CyclicAgent[] agents = (CyclicAgent[])this.agents; + wakeAgents(agents); + } } } diff --git a/src/main/java/scheduler/Scheduler.java b/src/main/java/scheduler/Scheduler.java index 670d786367e2f0cedac36c7a94d9feb9d2753754..bb2437f7d4ed4c41f50fbfb6b235c5e924f18525 100644 --- a/src/main/java/scheduler/Scheduler.java +++ b/src/main/java/scheduler/Scheduler.java @@ -1,10 +1,10 @@ package scheduler; -import behaviors.Wakeable; +import agents.Agent; public interface Scheduler { - void init(Wakeable[] agents); + void init(Agent[] agents); void doNextCycle(); } diff --git a/src/main/java/sma/SEIRS_SMA.java b/src/main/java/sma/SEIRS_SMA.java index d6352a8bf78e53fb5af22d12a89dfb81fe6063d1..50afb577fa495a13b51d765b75e9430401e5ebf7 100644 --- a/src/main/java/sma/SEIRS_SMA.java +++ b/src/main/java/sma/SEIRS_SMA.java @@ -1,13 +1,13 @@ package sma; -import agents.FairInfectionRWAgent; -import agents.SEIRSAgent; +import agents.Agent; +import agents.RandomWalkingAgent3P; +import agents.seirs.*; import agents.states.InfectedSEIRSState; import behaviors.Randomized; import environment.SEIRSEnvironment; import environment.WrappingChunkedSEIRSEnvironment; import models.Parameters; -import agents.RandomWalkingAgent; import environment.ChunkedSEIRSEnvironment; import scheduler.DeterministScheduler; import scheduler.FairAsynchronousScheduler; @@ -34,7 +34,7 @@ import java.util.List; public class SEIRS_SMA extends Randomized implements SMA{ private final Parameters parameters; - private final SEIRSAgent[] agents; + private final Agent[] agents; private SEIRSEnvironment environment; private Scheduler scheduler; private StatisticsCanvas statisticsCanvas; @@ -47,7 +47,11 @@ public class SEIRS_SMA extends Randomized implements SMA{ super(params.seed()); parameters = YamlReader.getParams(); r.setSeed(parameters.seed()); - agents = new RandomWalkingAgent[parameters.population()]; + if (parameters.threePhased()) { + agents = new ThreePhasedSEIRSAgent[parameters.population()]; + }else { + agents = new CyclicSEIRSAgent[parameters.population()]; + } initEnvironment(); initPopulation(); infectPatientZero(); @@ -59,7 +63,7 @@ public class SEIRS_SMA extends Randomized implements SMA{ private void initGraphics() { statisticsCanvas = new StatisticsCanvas(300,parameters.size()); - display = new DisplaySquaredEnvironment(environment,agents); + display = new DisplaySquaredEnvironment(environment,(SEIRSAgent[]) agents); fb.setSimulationCanvas(display); fb.setStatsCanvas(statisticsCanvas); @@ -99,11 +103,19 @@ public class SEIRS_SMA extends Randomized implements SMA{ private void initPopulation() { for (int i = 0; i<parameters.population();i++) { Point position = new Point(r.nextInt(parameters.size()),r.nextInt(parameters.size())); - SEIRSAgent agent; - if (parameters.infectionStacks()) { - agent = new RandomWalkingAgent(position,(parameters.seed()+i),environment); + Agent agent; + if (parameters.threePhased()){ + if (parameters.infectionStacks()) { + agent = new RandomWalkingAgent3P(position,(parameters.seed()+i),environment); + } else { + agent = new FairInfectionRWAgent3P(position,(parameters.seed()+i),environment); + } } else { - agent = new FairInfectionRWAgent(position,(parameters.seed()+i),environment); + if (parameters.infectionStacks()) { + agent = new RandomWalkingAgentCyclic(position,(parameters.seed()+i),environment); + } else { + agent = new FairInfectionRWAgentCyclic(position,(parameters.seed()+i),environment); + } } agents[i] = agent; } @@ -112,9 +124,9 @@ public class SEIRS_SMA extends Randomized implements SMA{ private void infectPatientZero() { for (int i=0 ; i< parameters.nbOfPatientZero(); i++) { int nextInt = (r.nextInt(parameters.population())); - SEIRSAgent agent = agents[nextInt]; + SEIRSAgent agent = (SEIRSAgent)agents[nextInt]; while (agent.getState() instanceof InfectedSEIRSState) { - agent = agents[(r.nextInt(parameters.population()))]; + agent = (SEIRSAgent)agents[(r.nextInt(parameters.population()))]; } agent.changeState(new InfectedSEIRSState(agent)); } @@ -139,9 +151,9 @@ public class SEIRS_SMA extends Randomized implements SMA{ private void initEnvironment() { if (parameters.wrappingWorld()) { - environment = new WrappingChunkedSEIRSEnvironment(parameters.size(),agents); + environment = new WrappingChunkedSEIRSEnvironment(parameters.size(),(SEIRSAgent[]) agents); } else { - environment = new ChunkedSEIRSEnvironment(parameters.size(),agents); + environment = new ChunkedSEIRSEnvironment(parameters.size(),(SEIRSAgent[]) agents); } } diff --git a/src/main/java/view/DisplaySquaredEnvironment.java b/src/main/java/view/DisplaySquaredEnvironment.java index 9979a7582dccba83661daee319cf5d6514546318..39317db0a2418b50f662964c30f7f454813516fb 100644 --- a/src/main/java/view/DisplaySquaredEnvironment.java +++ b/src/main/java/view/DisplaySquaredEnvironment.java @@ -1,6 +1,6 @@ package view; -import agents.SEIRSAgent; +import agents.seirs.SEIRSAgent; import agents.states.SEIRSState; import environment.ChunkedSEIRSEnvironment; import environment.SEIRSEnvironment; @@ -10,11 +10,11 @@ import java.awt.*; public class DisplaySquaredEnvironment extends JPanel { - private final SEIRSAgent[] SEIRSAgents; + private final SEIRSAgent[] CyclicSEIRSAgents; - public DisplaySquaredEnvironment(SEIRSEnvironment environment, SEIRSAgent[] SEIRSAgents) { + public DisplaySquaredEnvironment(SEIRSEnvironment environment, SEIRSAgent[] CyclicSEIRSAgents) { this.setDoubleBuffered(true); - this.SEIRSAgents = SEIRSAgents; + this.CyclicSEIRSAgents = CyclicSEIRSAgents; setSize(environment.getSize(),environment.getSize()); setVisible(true); } @@ -29,10 +29,10 @@ public class DisplaySquaredEnvironment extends JPanel { @Override public void paint(Graphics g) { super.paint(g); - for (SEIRSAgent SEIRSAgent : SEIRSAgents) { - if (SEIRSAgent != null) { - colorAgent(g, SEIRSAgent); - drawCenteredCircle(g, SEIRSAgent.getPosition().x, SEIRSAgent.getPosition().y); + for (SEIRSAgent agent : CyclicSEIRSAgents) { + if (agent != null) { + colorAgent(g, agent); + drawCenteredCircle(g, agent.getPosition().x, agent.getPosition().y); } } } diff --git a/src/main/resources/parameters.yaml b/src/main/resources/parameters.yaml index 59a063d0cf29a1f078d7ada55e8ec591524d3b9d..7e7cfa90d8f5ea7146d02d3af7b0cf1ec5bb9654 100644 --- a/src/main/resources/parameters.yaml +++ b/src/main/resources/parameters.yaml @@ -7,10 +7,11 @@ nbOfCycles: 2000 nbOfPatientZero: 1 population: 3000 recordExperiment: false -playRecord: true +playRecord: false seed: 120 size: 1000 wrappingWorld : true synchronousMode: false timeBetweenCycles: 0 -infectionStacks : false \ No newline at end of file +infectionStacks : false +threePhased : true \ No newline at end of file