Restructure
This commit is contained in:
parent
5868aa977d
commit
4631242e19
8 changed files with 170 additions and 60 deletions
|
@ -34,7 +34,7 @@ testing {
|
||||||
// Apply a specific Java toolchain to ease working on different environments.
|
// Apply a specific Java toolchain to ease working on different environments.
|
||||||
java {
|
java {
|
||||||
toolchain {
|
toolchain {
|
||||||
languageVersion.set(JavaLanguageVersion.of(17))
|
languageVersion.set(JavaLanguageVersion.of(20))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,3 +42,8 @@ application {
|
||||||
// Define the main class for the application.
|
// Define the main class for the application.
|
||||||
mainClass.set("simulation.MainSimulation")
|
mainClass.set("simulation.MainSimulation")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always execute all tests, even when not all tasks are up-to-date.
|
||||||
|
tasks.withType<Test> {
|
||||||
|
outputs.upToDateWhen { false }
|
||||||
|
}
|
|
@ -1,16 +1,21 @@
|
||||||
package simulation;
|
package simulation;
|
||||||
|
|
||||||
class Event {
|
class Event {
|
||||||
// Constructor, creates an event of a certain type that should be put in the event list at a certain time.
|
// Constructor, creates an event of a certain type that should be put in the
|
||||||
Event(int type, double timeOfEvent) {
|
// event list at a certain time.
|
||||||
|
Event(int type, double eventTimeStamp) throws IllegalArgumentException {
|
||||||
|
if (type > 3 || type < 1)
|
||||||
|
throw new IllegalArgumentException("Event type must be one of ARRIVAL, READY or MEASURE");
|
||||||
|
|
||||||
eventType = type;
|
eventType = type;
|
||||||
eventTime = timeOfEvent;
|
eventTime = eventTimeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty constructor (used by the event list constructor)
|
// Empty constructor (used by the event list constructor)
|
||||||
Event() { }
|
// Event() {
|
||||||
|
// }
|
||||||
|
|
||||||
public double eventTime;
|
public double eventTime;
|
||||||
public int eventType;
|
public int eventType;
|
||||||
public Event next = null;
|
public Event next = null; // Explicitly initialize to null
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,72 @@
|
||||||
package simulation;
|
package simulation;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
// Essentially a linked list of a non-template node type
|
||||||
public class EventList {
|
public class EventList {
|
||||||
private Event head, tail;
|
private Event head = null;
|
||||||
|
private Integer size = 0;
|
||||||
|
|
||||||
EventList() {
|
EventList() {
|
||||||
head = new Event();
|
|
||||||
tail = new Event();
|
|
||||||
head.next = tail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InsertEvent(int type, double TimeOfEvent) {
|
// Yes
|
||||||
Event temp, pretemp;
|
public Event getHead() {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
pretemp = this.head;
|
public Integer length() {
|
||||||
temp = this.head.next;
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
Event newEvent = new Event(type, TimeOfEvent);
|
public void insertEvent(Event newEvent) {
|
||||||
|
if (this.head == null) {
|
||||||
|
this.head = newEvent;
|
||||||
|
size += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Event cursor = this.head;
|
||||||
|
// int tries = 0;
|
||||||
// Find the right place in the list using a sliding window
|
// Find the right place in the list using a sliding window
|
||||||
while ((temp.eventTime < newEvent.eventTime) && (temp != tail)) {
|
while ((cursor.next != null) && (cursor.eventTime < newEvent.eventTime)) {
|
||||||
pretemp = temp;
|
cursor = cursor.next;
|
||||||
temp = temp.next;
|
// tries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
pretemp.next = newEvent;
|
if (cursor.eventTime > newEvent.eventTime) {
|
||||||
newEvent.next = temp;
|
newEvent.next = this.head;
|
||||||
|
this.head = newEvent;
|
||||||
|
} else {
|
||||||
|
newEvent.next = cursor.next;
|
||||||
|
cursor.next = newEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Event FetchEvent() {
|
// System.out.println("Tries: " + tries);
|
||||||
Event temp = head.next;
|
size += 1;
|
||||||
head.next = temp.next;
|
}
|
||||||
|
|
||||||
|
public Event popEvent() {
|
||||||
|
if (head == null)
|
||||||
|
return null;
|
||||||
|
Event temp = head;
|
||||||
|
head = head.next;
|
||||||
temp.next = null;
|
temp.next = null;
|
||||||
|
size -= 1;
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Event popFront() {
|
public Event fetchEvent() {
|
||||||
Event temp = head.next;
|
Event temp = head.next;
|
||||||
head.next = temp.next;
|
head.next = temp.next;
|
||||||
temp.next = null;
|
temp.next = null;
|
||||||
|
size -= 1;
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public Event popFront() {
|
||||||
|
// Event front = this.head;
|
||||||
|
// this.head = this.head.next;
|
||||||
|
// return front;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package simulation;
|
package simulation;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
// This class is only created to be able to store the global time.
|
// This class is only created to be able to store the global time.
|
||||||
public class GlobalSimulation{
|
public class GlobalSimulation {
|
||||||
public static final int ARRIVAL = 1, READY = 2, MEASURE = 3;
|
public static final int ARRIVAL = 1, READY = 2, MEASURE = 3;
|
||||||
public static double time = 0;
|
public static double time = 0;
|
||||||
|
public static Random rand = new Random();
|
||||||
}
|
}
|
|
@ -5,16 +5,15 @@ import java.io.*;
|
||||||
public class MainSimulation extends GlobalSimulation {
|
public class MainSimulation extends GlobalSimulation {
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
Event actEvent;
|
|
||||||
EventList myEventList = new EventList();
|
EventList myEventList = new EventList();
|
||||||
|
Event actEvent;
|
||||||
State actState = new State(myEventList);
|
State actState = new State(myEventList);
|
||||||
|
|
||||||
myEventList.InsertEvent(ARRIVAL, 0);
|
myEventList.insertEvent(new Event(ARRIVAL, 0));
|
||||||
myEventList.InsertEvent(MEASURE, 5);
|
myEventList.insertEvent(new Event(MEASURE, 5));
|
||||||
|
|
||||||
while (MainSimulation.time < 50000) {
|
while (MainSimulation.time < 50000) {
|
||||||
actEvent = myEventList.FetchEvent();
|
actEvent = myEventList.popEvent();
|
||||||
MainSimulation.time = actEvent.eventTime;
|
MainSimulation.time = actEvent.eventTime;
|
||||||
actState.TreatEvent(actEvent);
|
actState.TreatEvent(actEvent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,55 +3,44 @@ package simulation;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
class State extends GlobalSimulation {
|
class State extends GlobalSimulation {
|
||||||
|
|
||||||
public int numberInQueue = 0, accumulated = 0, noMeasurements = 0;
|
public int numberInQueue = 0, accumulated = 0, noMeasurements = 0;
|
||||||
|
private EventList eventList;
|
||||||
|
|
||||||
private EventList myEventList;
|
State(EventList eventList) {
|
||||||
|
this.eventList = eventList;
|
||||||
static Random slump = new Random();
|
|
||||||
|
|
||||||
State(EventList x) {
|
|
||||||
myEventList = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InsertEvent(int event, double timeOfEvent) {
|
|
||||||
myEventList.InsertEvent(event, timeOfEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dispatches the events to the right handler
|
||||||
public void TreatEvent(Event x) {
|
public void TreatEvent(Event x) {
|
||||||
switch (x.eventType) {
|
if (x.eventType == ARRIVAL)
|
||||||
case ARRIVAL:
|
|
||||||
arrival();
|
arrival();
|
||||||
break;
|
else if (x.eventType == READY)
|
||||||
case READY:
|
|
||||||
ready();
|
ready();
|
||||||
break;
|
else if (x.eventType == MEASURE)
|
||||||
case MEASURE:
|
|
||||||
measure();
|
measure();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private double generateMean(double mean) {
|
// Helper to generate a random number with certain statistical properties
|
||||||
return 2 * mean * slump.nextDouble();
|
private static double generateMean(double mean) {
|
||||||
|
return 2 * mean * rand.nextDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void arrival() {
|
private void arrival() {
|
||||||
if (numberInQueue == 0)
|
if (numberInQueue == 0)
|
||||||
InsertEvent(READY, time + generateMean(1));
|
eventList.insertEvent(new Event(READY, time + generateMean(1)));
|
||||||
numberInQueue++;
|
numberInQueue++;
|
||||||
InsertEvent(ARRIVAL, time + generateMean(2));
|
eventList.insertEvent(new Event(ARRIVAL, time + generateMean(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ready() {
|
private void ready() {
|
||||||
numberInQueue--;
|
numberInQueue--;
|
||||||
if (numberInQueue > 0)
|
if (numberInQueue > 0)
|
||||||
InsertEvent(READY, time + generateMean(1));
|
eventList.insertEvent(new Event(READY, time + generateMean(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void measure() {
|
private void measure() {
|
||||||
accumulated = accumulated + numberInQueue;
|
accumulated = accumulated + numberInQueue;
|
||||||
noMeasurements++;
|
noMeasurements++;
|
||||||
InsertEvent(MEASURE, time + generateMean(5));
|
eventList.insertEvent(new Event(MEASURE, time + generateMean(5)));
|
||||||
}
|
}
|
||||||
}
|
}
|
63
app/src/test/java/simulation/EventListTest.java
Normal file
63
app/src/test/java/simulation/EventListTest.java
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
package simulation;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class EventListTest {
|
||||||
|
@Test
|
||||||
|
void testEventListConstructor() {
|
||||||
|
EventList eventList = new EventList();
|
||||||
|
Event event = new Event(1, 0.0);
|
||||||
|
eventList.insertEvent(event);
|
||||||
|
assert eventList.getHead() == event;
|
||||||
|
assert eventList.getHead().next == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOrdering() {
|
||||||
|
EventList eventList = new EventList();
|
||||||
|
Event event1 = new Event(1, 0.0);
|
||||||
|
Event event2 = new Event(1, 1.0);
|
||||||
|
Event event3 = new Event(1, 2.0);
|
||||||
|
eventList.insertEvent(event3);
|
||||||
|
eventList.insertEvent(event2);
|
||||||
|
eventList.insertEvent(event1);
|
||||||
|
assert eventList.getHead() == event1;
|
||||||
|
assert eventList.getHead().next == event2;
|
||||||
|
assert eventList.getHead().next.next == event3;
|
||||||
|
assert eventList.getHead().next.next.next == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testLength() {
|
||||||
|
Random rand = new Random();
|
||||||
|
EventList eventList = new EventList();
|
||||||
|
for(int i : rand.ints(0, 100).limit(100).toArray()) {
|
||||||
|
eventList.insertEvent(new Event(1, (double) i));
|
||||||
|
}
|
||||||
|
assert eventList.length() == 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPop() {
|
||||||
|
EventList eventList = new EventList();
|
||||||
|
Event event1 = new Event(1, 0.0);
|
||||||
|
eventList.insertEvent(event1);
|
||||||
|
assert eventList.popEvent() == event1;
|
||||||
|
assert eventList.popEvent() == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOrderingRandomAmount() {
|
||||||
|
Random rand = new Random();
|
||||||
|
EventList eventList = new EventList();
|
||||||
|
for(int i : rand.ints(0, 100).limit(100).toArray()) {
|
||||||
|
eventList.insertEvent(new Event(1, (double) i));
|
||||||
|
}
|
||||||
|
for(Event e = eventList.getHead(); e != null; e = eventList.popEvent()) {
|
||||||
|
if(e.next == null) break;
|
||||||
|
assert e.eventTime < e.next.eventTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
app/src/test/java/simulation/EventTest.java
Normal file
17
app/src/test/java/simulation/EventTest.java
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package simulation;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class EventTest {
|
||||||
|
@Test void testConstructor() {
|
||||||
|
Event event = new Event(1, 0.0);
|
||||||
|
assert event.eventType == 1;
|
||||||
|
assert event.eventTime == 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test void testEmptyConstructor() {
|
||||||
|
// Event event = new Event();
|
||||||
|
// assert event.eventType == 0;
|
||||||
|
// assert event.eventTime == 0.0;
|
||||||
|
// }
|
||||||
|
}
|
Loading…
Reference in a new issue