This commit is contained in:
Imbus 2023-09-29 07:31:06 +02:00
parent 4631242e19
commit a86f928f36
7 changed files with 64 additions and 102 deletions

View file

@ -1,8 +1,12 @@
package simulation;
class Event {
class Event implements Comparable<Event> {
// Our only data members, we don't want anyone to tamper with these
private double eventTime;
private int eventType;
// Constructor, creates an event of a certain type that should be put in the
// event list at a certain time.
// event list at a certain time. Throws if type is out of bounds.
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");
@ -11,11 +15,17 @@ class Event {
eventTime = eventTimeStamp;
}
// Empty constructor (used by the event list constructor)
// Event() {
// }
public double eventTime;
public int eventType;
public Event next = null; // Explicitly initialize to null
// Setters and getters for the private variables instead of having them public
public double getEventTime() {
return eventTime;
}
public int getEventType() {
return eventType;
}
// This is the custom comparator that PriorityQueue uses to sort the events
@Override
public int compareTo(Event e) {
return Double.compare(eventTime, e.eventTime);
}
}

View file

@ -1,72 +1,41 @@
package simulation;
import java.util.LinkedList;
import java.util.PriorityQueue;
// Essentially a linked list of a non-template node type
// Wrapper class for a priority queue of events
// Changed from a linked list to a priority queue better suited for this type of application
public class EventList {
private Event head = null;
private Integer size = 0;
EventList() {
// A heap backed, event containing priority queue.
private PriorityQueue<Event> pq = new PriorityQueue<>();
// This one contains events that are prioritized over the normal events
private PriorityQueue<Event> high_pq = new PriorityQueue<>();
// This is a helper function to get the correct queue
private PriorityQueue<Event> getQueue() {
return switch(high_pq.size()) {
case 0 -> pq; // If no priority events, return normal queue
default -> high_pq; // If priority events, return priority queue
};
}
// Yes
public Event getHead() {
return head;
return getQueue().peek();
}
public Integer length() {
return size;
return getQueue().size();
}
public void insertEvent(Event newEvent) {
if (this.head == null) {
this.head = newEvent;
size += 1;
return;
pq.add(newEvent);
}
Event cursor = this.head;
// int tries = 0;
// Find the right place in the list using a sliding window
while ((cursor.next != null) && (cursor.eventTime < newEvent.eventTime)) {
cursor = cursor.next;
// tries++;
}
if (cursor.eventTime > newEvent.eventTime) {
newEvent.next = this.head;
this.head = newEvent;
} else {
newEvent.next = cursor.next;
cursor.next = newEvent;
}
// System.out.println("Tries: " + tries);
size += 1;
public void insertPriorityEvent(Event newEvent) {
high_pq.add(newEvent);
}
public Event popEvent() {
if (head == null)
return null;
Event temp = head;
head = head.next;
temp.next = null;
size -= 1;
return temp;
return getQueue().poll();
}
public Event fetchEvent() {
Event temp = head.next;
head.next = temp.next;
temp.next = null;
size -= 1;
return temp;
}
// public Event popFront() {
// Event front = this.head;
// this.head = this.head.next;
// return front;
// }
}

View file

@ -12,9 +12,9 @@ public class MainSimulation extends GlobalSimulation {
myEventList.insertEvent(new Event(ARRIVAL, 0));
myEventList.insertEvent(new Event(MEASURE, 5));
while (MainSimulation.time < 50000) {
while (MainSimulation.time < 200000) {
actEvent = myEventList.popEvent();
MainSimulation.time = actEvent.eventTime;
MainSimulation.time = actEvent.getEventTime();
actState.TreatEvent(actEvent);
}

View file

@ -1,23 +1,22 @@
package simulation;
import java.util.*;
class State extends GlobalSimulation {
public int numberInQueue = 0, accumulated = 0, noMeasurements = 0;
private EventList eventList;
private EventList eventList = null;
State(EventList eventList) {
this.eventList = eventList;
}
// Dispatches the events to the right handler
public void TreatEvent(Event x) {
if (x.eventType == ARRIVAL)
arrival();
else if (x.eventType == READY)
ready();
else if (x.eventType == MEASURE)
measure();
// Dispatches the events to the right handler with a java 20 switch statement
public void TreatEvent(Event event) {
switch (event.getEventType()) {
case ARRIVAL -> arrival();
case READY -> ready();
case MEASURE -> measure();
}
// System.out.println(String.format("Event type: %d, Customers: %d, Time: %.1f",
// event.getEventType(), numberInQueue, event.getEventTime()));
}
// Helper to generate a random number with certain statistical properties
@ -28,8 +27,8 @@ class State extends GlobalSimulation {
private void arrival() {
if (numberInQueue == 0)
eventList.insertEvent(new Event(READY, time + generateMean(1)));
numberInQueue++;
eventList.insertEvent(new Event(ARRIVAL, time + generateMean(2)));
numberInQueue++;
}
private void ready() {

View file

@ -1,12 +0,0 @@
package simulation;
// import org.junit.jupiter.api.Test;
// import static org.junit.jupiter.api.Assertions.*;
// No defined tests yet
class AppTest {
// @Test void appHasAGreeting() {
// App classUnderTest = new App();
// assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
// }
}

View file

@ -11,7 +11,6 @@ public class EventListTest {
Event event = new Event(1, 0.0);
eventList.insertEvent(event);
assert eventList.getHead() == event;
assert eventList.getHead().next == null;
}
@Test
@ -23,10 +22,10 @@ public class EventListTest {
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;
assert eventList.popEvent() == event1;
assert eventList.popEvent() == event2;
assert eventList.popEvent() == event3;
assert eventList.popEvent() == null;
}
@Test
@ -55,9 +54,11 @@ public class EventListTest {
for(int i : rand.ints(0, 100).limit(100).toArray()) {
eventList.insertEvent(new Event(1, (double) i));
}
Event prev = eventList.popEvent();
for(Event e = eventList.getHead(); e != null; e = eventList.popEvent()) {
if(e.next == null) break;
assert e.eventTime < e.next.eventTime;
assert prev.getEventTime() <= e.getEventTime();
prev = e;
}
}
}

View file

@ -3,15 +3,10 @@ package simulation;
import org.junit.jupiter.api.Test;
public class EventTest {
@Test void testConstructor() {
@Test
void testConstructor() {
Event event = new Event(1, 0.0);
assert event.eventType == 1;
assert event.eventTime == 0.0;
assert event.getEventType() == 1;
assert event.getEventTime() == 0.0;
}
// @Test void testEmptyConstructor() {
// Event event = new Event();
// assert event.eventType == 0;
// assert event.eventTime == 0.0;
// }
}