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) { | ||||||
| 		// Find the right place in the list using a sliding window | 			this.head = newEvent; | ||||||
| 		while ((temp.eventTime < newEvent.eventTime) && (temp != tail)) { | 			size += 1; | ||||||
| 			pretemp = temp; | 			return; | ||||||
| 			temp = temp.next; |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		pretemp.next = newEvent; | 		Event cursor = this.head; | ||||||
| 		newEvent.next = temp; | 		// 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 Event FetchEvent() { | 	public Event popEvent() { | ||||||
| 		Event temp = head.next; | 		if (head == null) | ||||||
| 		head.next = temp.next; | 			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(); | 		else if (x.eventType == READY) | ||||||
| 				break; | 			ready(); | ||||||
| 			case READY: | 		else if (x.eventType == MEASURE) | ||||||
| 				ready(); | 			measure(); | ||||||
| 				break; |  | ||||||
| 			case 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Imbus
						Imbus