Polish
This commit is contained in:
parent
4631242e19
commit
a86f928f36
7 changed files with 64 additions and 102 deletions
|
@ -1,8 +1,12 @@
|
||||||
package simulation;
|
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
|
// 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 {
|
Event(int type, double eventTimeStamp) throws IllegalArgumentException {
|
||||||
if (type > 3 || type < 1)
|
if (type > 3 || type < 1)
|
||||||
throw new IllegalArgumentException("Event type must be one of ARRIVAL, READY or MEASURE");
|
throw new IllegalArgumentException("Event type must be one of ARRIVAL, READY or MEASURE");
|
||||||
|
@ -11,11 +15,17 @@ class Event {
|
||||||
eventTime = eventTimeStamp;
|
eventTime = eventTimeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty constructor (used by the event list constructor)
|
// Setters and getters for the private variables instead of having them public
|
||||||
// Event() {
|
public double getEventTime() {
|
||||||
// }
|
return eventTime;
|
||||||
|
}
|
||||||
|
public int getEventType() {
|
||||||
|
return eventType;
|
||||||
|
}
|
||||||
|
|
||||||
public double eventTime;
|
// This is the custom comparator that PriorityQueue uses to sort the events
|
||||||
public int eventType;
|
@Override
|
||||||
public Event next = null; // Explicitly initialize to null
|
public int compareTo(Event e) {
|
||||||
|
return Double.compare(eventTime, e.eventTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,72 +1,41 @@
|
||||||
package simulation;
|
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 {
|
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() {
|
public Event getHead() {
|
||||||
return head;
|
return getQueue().peek();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer length() {
|
public Integer length() {
|
||||||
return size;
|
return getQueue().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertEvent(Event newEvent) {
|
public void insertEvent(Event newEvent) {
|
||||||
if (this.head == null) {
|
pq.add(newEvent);
|
||||||
this.head = newEvent;
|
|
||||||
size += 1;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Event cursor = this.head;
|
public void insertPriorityEvent(Event newEvent) {
|
||||||
// int tries = 0;
|
high_pq.add(newEvent);
|
||||||
// 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 Event popEvent() {
|
public Event popEvent() {
|
||||||
if (head == null)
|
return getQueue().poll();
|
||||||
return null;
|
|
||||||
Event temp = head;
|
|
||||||
head = head.next;
|
|
||||||
temp.next = null;
|
|
||||||
size -= 1;
|
|
||||||
return temp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,9 @@ public class MainSimulation extends GlobalSimulation {
|
||||||
myEventList.insertEvent(new Event(ARRIVAL, 0));
|
myEventList.insertEvent(new Event(ARRIVAL, 0));
|
||||||
myEventList.insertEvent(new Event(MEASURE, 5));
|
myEventList.insertEvent(new Event(MEASURE, 5));
|
||||||
|
|
||||||
while (MainSimulation.time < 50000) {
|
while (MainSimulation.time < 200000) {
|
||||||
actEvent = myEventList.popEvent();
|
actEvent = myEventList.popEvent();
|
||||||
MainSimulation.time = actEvent.eventTime;
|
MainSimulation.time = actEvent.getEventTime();
|
||||||
actState.TreatEvent(actEvent);
|
actState.TreatEvent(actEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,22 @@
|
||||||
package simulation;
|
package simulation;
|
||||||
|
|
||||||
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 eventList = null;
|
||||||
|
|
||||||
State(EventList eventList) {
|
State(EventList eventList) {
|
||||||
this.eventList = eventList;
|
this.eventList = eventList;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatches the events to the right handler
|
// Dispatches the events to the right handler with a java 20 switch statement
|
||||||
public void TreatEvent(Event x) {
|
public void TreatEvent(Event event) {
|
||||||
if (x.eventType == ARRIVAL)
|
switch (event.getEventType()) {
|
||||||
arrival();
|
case ARRIVAL -> arrival();
|
||||||
else if (x.eventType == READY)
|
case READY -> ready();
|
||||||
ready();
|
case MEASURE -> measure();
|
||||||
else if (x.eventType == 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
|
// Helper to generate a random number with certain statistical properties
|
||||||
|
@ -28,8 +27,8 @@ class State extends GlobalSimulation {
|
||||||
private void arrival() {
|
private void arrival() {
|
||||||
if (numberInQueue == 0)
|
if (numberInQueue == 0)
|
||||||
eventList.insertEvent(new Event(READY, time + generateMean(1)));
|
eventList.insertEvent(new Event(READY, time + generateMean(1)));
|
||||||
numberInQueue++;
|
|
||||||
eventList.insertEvent(new Event(ARRIVAL, time + generateMean(2)));
|
eventList.insertEvent(new Event(ARRIVAL, time + generateMean(2)));
|
||||||
|
numberInQueue++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ready() {
|
private void ready() {
|
||||||
|
|
|
@ -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");
|
|
||||||
// }
|
|
||||||
}
|
|
|
@ -11,7 +11,6 @@ public class EventListTest {
|
||||||
Event event = new Event(1, 0.0);
|
Event event = new Event(1, 0.0);
|
||||||
eventList.insertEvent(event);
|
eventList.insertEvent(event);
|
||||||
assert eventList.getHead() == event;
|
assert eventList.getHead() == event;
|
||||||
assert eventList.getHead().next == null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -23,10 +22,10 @@ public class EventListTest {
|
||||||
eventList.insertEvent(event3);
|
eventList.insertEvent(event3);
|
||||||
eventList.insertEvent(event2);
|
eventList.insertEvent(event2);
|
||||||
eventList.insertEvent(event1);
|
eventList.insertEvent(event1);
|
||||||
assert eventList.getHead() == event1;
|
assert eventList.popEvent() == event1;
|
||||||
assert eventList.getHead().next == event2;
|
assert eventList.popEvent() == event2;
|
||||||
assert eventList.getHead().next.next == event3;
|
assert eventList.popEvent() == event3;
|
||||||
assert eventList.getHead().next.next.next == null;
|
assert eventList.popEvent() == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -55,9 +54,11 @@ public class EventListTest {
|
||||||
for(int i : rand.ints(0, 100).limit(100).toArray()) {
|
for(int i : rand.ints(0, 100).limit(100).toArray()) {
|
||||||
eventList.insertEvent(new Event(1, (double) i));
|
eventList.insertEvent(new Event(1, (double) i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Event prev = eventList.popEvent();
|
||||||
for(Event e = eventList.getHead(); e != null; e = eventList.popEvent()) {
|
for(Event e = eventList.getHead(); e != null; e = eventList.popEvent()) {
|
||||||
if(e.next == null) break;
|
assert prev.getEventTime() <= e.getEventTime();
|
||||||
assert e.eventTime < e.next.eventTime;
|
prev = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,10 @@ package simulation;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class EventTest {
|
public class EventTest {
|
||||||
@Test void testConstructor() {
|
@Test
|
||||||
|
void testConstructor() {
|
||||||
Event event = new Event(1, 0.0);
|
Event event = new Event(1, 0.0);
|
||||||
assert event.eventType == 1;
|
assert event.getEventType() == 1;
|
||||||
assert event.eventTime == 0.0;
|
assert event.getEventTime() == 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test void testEmptyConstructor() {
|
|
||||||
// Event event = new Event();
|
|
||||||
// assert event.eventType == 0;
|
|
||||||
// assert event.eventTime == 0.0;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue