import java.util.Random;
//old one had one lineup for each of 2 windows, we are just going to have one big line up now
public class driver {
public static final double SIM_TIME = 21600;
public static final int SECONDS_PER_HOUR = 3600;
public static double currentTime, totalWaitTime, maxWaitTime, queue1LengthTime, lastTime = 0;
public static EventQueue queue;
public static CustomerQueue lineup1;
public static boolean window1IsIdle, window2IsIdle, window3IsIdle, window4IsIdle;
public static int customersServed, nextCustomerNumber, maxQueueLength = 0;
public static void scheduleNextCustomerGroup(double time){
Random generator = new Random();
double number = 100*generator.nextDouble();
if (number <= 30){
custGroupJoinQ e = new custGroupJoinQ(time, 1);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}//1 customer
else if (number <= 70){
custGroupJoinQ e = new custGroupJoinQ(time,2);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}//2 customer
else if (number <= 90){
custGroupJoinQ e = new custGroupJoinQ(time,3);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}//3 customer
else if (number <= 95){
custGroupJoinQ e = new custGroupJoinQ(time,4);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}//4 customer
else if (number <= 98){
custGroupJoinQ e = new custGroupJoinQ(time,5);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}//5 customer
else if (number <= 100){
custGroupJoinQ e = new custGroupJoinQ(time,6);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}//6 customer
}
public static void scheduleNextServiceStart1(double time){
serviceStart1 e = new serviceStart1(time);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}
public static void scheduleNextServiceStart2(double time){
serviceStart2 e = new serviceStart2(time);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}
public static void scheduleNextServiceStart3(double time){
serviceStart3 e = new serviceStart3(time);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}
public static void scheduleNextServiceStart4(double time){
serviceStart4 e = new serviceStart4(time);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}
public static void scheduleNextServiceEnd1(double time){
serviceEnd1 e = new serviceEnd1(time);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}
public static void scheduleNextServiceEnd2(double time){
serviceEnd2 e = new serviceEnd2(time);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}
public static void scheduleNextServiceEnd3(double time){
serviceEnd3 e = new serviceEnd3(time);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}
public static void scheduleNextServiceEnd4(double time){
serviceEnd4 e = new serviceEnd4(time);
queue.Enqueue(e);
System.out.println(currentTime+e.toString());
}
public static void openForBuisiness(){
System.out.println(currentTime+”open for business”);
currentTime = 0;
nextCustomerNumber = 1;
queue = new EventQueue();
lineup1 = new CustomerQueue();
window1IsIdle = true;
window2IsIdle = true;
window3IsIdle = true;
window4IsIdle = true;
scheduleNextCustomerGroup(currentTime + generateArrivalTime());
}
public static void acceptCustomer(double time) {
System.out.println(currentTime + ” there is a customer in lineup1: “+!lineup1.isEmpty());
System.out.println(currentTime + ” window 1 is available: “+window1IsIdle);
System.out.println(currentTime + ” window 2 is available: “+window2IsIdle);
System.out.println(currentTime + ” window 3 is available: “+window3IsIdle);
System.out.println(currentTime + ” window 4 is available: “+window4IsIdle);
if ( (!lineup1.isEmpty()) && window1IsIdle) scheduleNextServiceStart1(time);
else if ( (!lineup1.isEmpty()) && window2IsIdle) scheduleNextServiceStart2(time);
else if ( (!lineup1.isEmpty()) && window3IsIdle) scheduleNextServiceStart3(time);
else if ( (!lineup1.isEmpty()) && window4IsIdle) scheduleNextServiceStart4(time);
}
public static void addNewCustToLineup1(){
Customer customer = new Customer(nextCustomerNumber);
nextCustomerNumber++;
customer.setTimeJoinQueue(currentTime);
lineup1.joinQ(customer);
}
public static void removeCustFromFront1(){
updateStats(lineup1.leaveQ());
}
public static void processEvent(){
Event event;
event = queue.Dequeue();
currentTime = event.scheduledTime;
if (event.eventType == “custGroupJoinQ”) {
for (int i=0; i < ((custGroupJoinQ)event).numberOfCustomers; i++)
{addNewCustToLineup1();System.out.println(currentTime+” EVENT:custGroupJoinQ – customer added to lineup1. lineup1 length:”+lineup1.length);}
scheduleNextCustomerGroup(currentTime + generateArrivalTime());
}
if (event.eventType == “serviceStart1″){
removeCustFromFront1();
System.out.println(currentTime+” EVENT:serviceStart1 – customer removed from lineup1. lineup1 length:”+lineup1.length);
scheduleNextServiceEnd1(currentTime + generateServiceTime());
window1IsIdle = false;
}
if (event.eventType == “serviceStart2″){
removeCustFromFront1();
System.out.println(currentTime+” EVENT:serviceStart2 – customer removed from lineup1. lineup1 length:”+lineup1.length);
scheduleNextServiceEnd2(currentTime + generateServiceTime());
window2IsIdle = false;
}
if (event.eventType == “serviceStart3″){
removeCustFromFront1();
System.out.println(currentTime+” EVENT:serviceStart3 – customer removed from lineup1. lineup1 length:”+lineup1.length);
scheduleNextServiceEnd3(currentTime + generateServiceTime());
window3IsIdle = false;
}
if (event.eventType == “serviceStart4″){
removeCustFromFront1();
System.out.println(currentTime+” EVENT:serviceStart4 – customer removed from lineup1. lineup1 length:”+lineup1.length);
scheduleNextServiceEnd4(currentTime + generateServiceTime());
window4IsIdle = false;
}
if (event.eventType == “serviceEnd1″){
System.out.println(currentTime+” EVENT:serviceEnd1″);
window1IsIdle = true;
}
if (event.eventType == “serviceEnd2″){
System.out.println(currentTime+” EVENT:serviceEnd2″);
window2IsIdle = true;
}
if (event.eventType == “serviceEnd3″){
System.out.println(currentTime+” EVENT:serviceEnd3″);
window3IsIdle = true;
}
if (event.eventType == “serviceEnd4″){
System.out.println(currentTime+” EVENT:serviceEnd4″);
window4IsIdle = true;
}
}
public static void updateStats(Customer customer){
double waitTime;
customer.setTimeToWindow(currentTime – customer.timeJoinedQueue);
waitTime = customer.timeToWindow;
if (waitTime > maxWaitTime) maxWaitTime = waitTime;
if (lineup1.length > maxQueueLength) maxQueueLength = lineup1.length;
totalWaitTime = totalWaitTime + waitTime;
customersServed++; //System.out.println(“”+customersServed);
queue1LengthTime = lineup1.length * (currentTime – lastTime) + queue1LengthTime;
lastTime = currentTime;
}
public static void reportStats(){
System.out.println(“customers served: “+ customersServed);
System.out.println(“average customers served per hour: ” + customersServed / (SIM_TIME/SECONDS_PER_HOUR));
System.out.println(“average wait time in queue for each customer: ” + totalWaitTime/customersServed + ” seconds”);
System.out.println(“the longest any customer had to wait was: ” + maxWaitTime +” seconds”);
System.out.println(“the average queue length was: “+ queue1LengthTime / SIM_TIME);
System.out.println(“the maximum queue length was ” + maxQueueLength);
}
public static double generateArrivalTime(){
Random generator = new Random();
return 10 + Math.abs(100*generator.nextDouble());
}
public static double generateServiceTime(){
Random generator = new Random();
return 55 + Math.abs(130*generator.nextDouble());
}
public static void main(String[] args) {
openForBuisiness();
while (currentTime < SIM_TIME){
System.out.println(currentTime+”process event”);
processEvent();
System.out.println(currentTime+”accept customer”);
acceptCustomer(currentTime);
}
reportStats();
}
}
EventQueue.java
import java.util.Comparator;
import java.util.PriorityQueue;
public class EventQueue {
PriorityQueue<Event> queue;
Comparator<Event> comparator;
public EventQueue(){
comparator = new EventComparator();
queue = new PriorityQueue<Event>(1, comparator);
}
public boolean Enqueue(Event e){
return queue.add(e);
}
public Event Dequeue(){
return queue.poll();
}
public int size(){
return queue.size();
}
}
Event.java
public class Event {
String eventType;
double scheduledTime;
public Event(){
eventType = “”;
scheduledTime=0;
}
public Event(String type, double time) {
eventType = type;
scheduledTime = time;
}
public String toString(){
return eventType+ ” “+ scheduledTime;
}
}
CustomerQueue.java
public class CustomerQueue extends LinkedListForCustQ {
int length, maxLength, totalCustomers;
Customer info;
public CustomerQueue() {
super();
length = 0;
maxLength = 0;
totalCustomers = 0;
info = null;
}
public void joinQ(Customer customer) {
queueJoin(customer);
totalCustomers++;
length++;
if (length > maxLength) maxLength = length;
}
public Customer leaveQ() {
length–;
totalCustomers–;
return queueLeave();
}
}
LinkedListForCustQ.java
public class LinkedListForCustQ {
// this class implements the standard abstract data type linked list as an object
Customer info;
LinkedListForCustQ nextList;
boolean amEmpty;
// interface methods here
// QUEUE interface
public void queueJoin(Customer inInfo) {
// Join(info): info becomes the end of the QUEUE the last item inserted
this.insertInfo(inInfo);
}
public Customer queueLeave() {
// info <– Leave(): if the queue is empty nothing is returned
// if the queue is not empty the last item in the list is returned and removed from the queue
if (this.isEmpty()) { return null;}
// if last item in list return and remove else leave from rest of queue
Customer tempCust;
if (this.nextList.isEmpty()) {
tempCust = this.info;
this.deleteInfo(tempCust);
} else {
// get from later in list
tempCust = this.nextList.queueLeave();
}
return tempCust;
}
// end of interface methods
public LinkedListForCustQ() {
info = null;
nextList = null;
amEmpty = true;
}
public boolean isEmpty() {
return (amEmpty);
}
public void insertInfo(Customer inInfo) {
if (this.amEmpty) {
LinkedListForCustQ tempLList = new LinkedListForCustQ();
// insert info here and add a new empty at end
info = inInfo;
nextList = tempLList;
amEmpty = false;
}
else {
this.nextList.insertInfo(this.info);
this.info = inInfo;
}
}
public void deleteInfo(Customer outInfo) {
if (this.amEmpty)
return;
// check if this is the info to delete
if (this.info.customerNumber != outInfo.customerNumber) {
// System.out.println(“Didn’t match so looking further down list”);
this.nextList.deleteInfo(outInfo);
return;
}
// found it so delete it
if (this.nextList.isEmpty()) {
this.nextList = null;
this.info = null;
amEmpty = true;
// System.out.println(“Deleting from last element”);
}
else {
this.info = this.nextList.info; // copy next info to current
this.nextList.deleteInfo(this.info);
// System.out.println(“Shifted info forward and deleting down rest of list”);
}
}
public String traverseList() {
// add current content to list returned by the rest of the list
if (this.isEmpty())
return “”;
if (this.nextList.isEmpty())
return “customer number: “+this.info.customerNumber;
return “customer number: “+this.info.customerNumber+”, “+this.nextList.traverseList();
}
}
Customer.java
public class Customer {
int customerNumber;
double timeJoinedQueue, timeToWindow;
public Customer () {customerNumber = 0; timeJoinedQueue = 0; timeToWindow = 0; }
public Customer (int number) {customerNumber = number; timeJoinedQueue = 0; timeToWindow = 0;}
public void setTimeJoinQueue(double time) {timeJoinedQueue = time;}
public void setTimeToWindow(double time) {timeToWindow = time;}
public double timeInQueue(double currentTime) {return currentTime – timeJoinedQueue;}
public double timeAtWindow(double currentTime) {return currentTime – timeToWindow – timeJoinedQueue;}
}
EventComparator.java
import java.util.Comparator;
public class EventComparator implements Comparator<Event>
{
@Override
public int compare(Event x, Event y)
{
if (x.scheduledTime < y.scheduledTime)
{
return -1;
}
if (x.scheduledTime > y.scheduledTime)
{
return 1;
}
if (x.scheduledTime == y.scheduledTime)//always handle customers joining the queue first
{
if(x.eventType == “custJoinQ”)
{
return 1;
}
else if (y.eventType == “custJoinQ”)
{
return -1;
}
if(x.eventType == “serviceEnd1”)
{
return 1;
}
else if (y.eventType == “serviceEnd1”)
{
return -1;
}
if(x.eventType == “serviceEnd2”)
{
return 1;
}
else if (y.eventType == “serviceEnd2”)
{
return -1;
}
if(x.eventType == “serviceStart1”)
{
return 1;
}
else if (y.eventType == “serviceStart1”)
{
return -1;
}
if(x.eventType == “serviceStart2”)
{
return 1;
}
else if (y.eventType == “serviceStart2”)
{
return -1;
}
}
return 0;
}
}
custGroupJoinQ.java
public class custGroupJoinQ extends Event {
int numberOfCustomers;
public custGroupJoinQ(double time) {
eventType = “custGroupJoinQ”;
scheduledTime = time;
numberOfCustomers =1;
}
public custGroupJoinQ(double time, int numcust) {
eventType = “custGroupJoinQ”;
scheduledTime = time;
numberOfCustomers = numcust;
}
public void generateNext(EventQueue queue, double time){
custGroupJoinQ event = new custGroupJoinQ(time);
queue.Enqueue(event);
return;
}
}
serviceStart1.java
public class serviceStart1 extends Event {
public serviceStart1(double time) {
eventType = “serviceStart1”;
scheduledTime = time;
}
public void generateNext(EventQueue queue, double time){
serviceStart1 event = new serviceStart1(time);
queue.Enqueue(event);
return;
}
}
serviceStart2.java
public class serviceStart2 extends Event {
public serviceStart2(double time) {
eventType = “serviceStart2”;
scheduledTime = time;
}
public void generateNext(EventQueue queue, double time){
serviceStart2 event = new serviceStart2(time);
queue.Enqueue(event);
return;
}
}
serviceStart3.java
public class serviceStart3 extends Event {
public serviceStart3(double time) {
eventType = “serviceStart3”;
scheduledTime = time;
}
public void generateNext(EventQueue queue, double time){
serviceStart3 event = new serviceStart3(time);
queue.Enqueue(event);
return;
}
}
serviceStart4.java
public class serviceStart4 extends Event {
public serviceStart4(double time) {
eventType = “serviceStart4”;
scheduledTime = time;
}
public void generateNext(EventQueue queue, double time){
serviceStart4 event = new serviceStart4(time);
queue.Enqueue(event);
return;
}
}
serviceEnd2.java
public class serviceEnd2 extends Event {
public serviceEnd2(double time) {
eventType = “serviceEnd2”;
scheduledTime = time;
}
public void generateNext(EventQueue queue, double time){
serviceEnd2 event = new serviceEnd2(time);
queue.Enqueue(event);
return;
}
}
serviceEnd1.java
public class serviceEnd1 extends Event {
public serviceEnd1(double time) {
eventType = “serviceEnd1”;
scheduledTime = time;
}
public void generateNext(EventQueue queue, double time){
serviceEnd1 event = new serviceEnd1(time);
queue.Enqueue(event);
return;
}
}
serviceEnd3.java
public class serviceEnd3 extends Event {
public serviceEnd3(double time) {
eventType = “serviceEnd3”;
scheduledTime = time;
}
public void generateNext(EventQueue queue, double time){
serviceEnd3 event = new serviceEnd3(time);
queue.Enqueue(event);
return;
}
}
serviceEnd4.java
public class serviceEnd4 extends Event {
public serviceEnd4(double time) {
eventType = “serviceEnd4”;
scheduledTime = time;
}
public void generateNext(EventQueue queue, double time){
serviceEnd4 event = new serviceEnd4(time);
queue.Enqueue(event);
return;
}
}
