Restructure

This commit is contained in:
Imbus 2023-09-29 05:23:52 +02:00
parent 5868aa977d
commit 4631242e19
8 changed files with 170 additions and 60 deletions

View file

@ -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 }
}

View file

@ -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
} }

View file

@ -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;
// }
} }

View file

@ -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();
} }

View file

@ -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);
} }

View file

@ -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)));
} }
} }

View 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;
}
}
}

View 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;
// }
}