-
package waitingQueues.model;
-
-
import java.util.ArrayList;
-
-
import waitingQueues.Constants;
-
import waitingQueues.WaitingQueuesException;
-
-
/**
-
* The purpose of the Model is to set the input parameters on which the
-
* simulation will run, to generate the persons and them queues, manages those
-
* and retrieve the queue content.
-
*
-
* @author Marian Dan
-
*
-
*/
-
public class Model implements ModelInterface {
-
/**
-
* Default constructor
-
*/
-
public Model() {
-
availableQueues = -1;
-
personArray = new ArrayList();
-
officeOpened = false;
-
message = "";
-
simulationTime = 0;
-
averageTime = 0.0;
-
}
-
-
/**
-
* It passes a message to the controller that will redirect it to the view.
-
* The message will be displayed in the description field in the InputForm.
-
*/
-
public String passMessage() {
-
String mess = message;
-
message = "";
-
return mess;
-
}
-
-
/**
-
* Returns a String representation of the simulation time.
-
*/
-
public String getSimulationTime() {
-
return "" + simulationTime;
-
-
}
-
-
/**
-
* It returns true if the office has been opened.
-
*
-
* @return true if the office has been opened, false otherwise
-
*/
-
public boolean hasTheOfficeOpened() {
-
// return availableQueues >= 0;
-
return officeOpened;
-
}
-
-
/**
-
* Returns an array of strings containing a representation of person’s
-
* characteristics.
-
*
-
* @return
-
*/
-
public String[] getQueueContent(int index) {
-
// precondition
-
if (array == null)
-
throw new AssertionError("For some reason the queue is invalid");
-
if (index < 0 || index >= array.length)
-
throw new IllegalArgumentException("Values " + index
-
+ " violate the precondition");
-
-
if (array[index] == null) {
-
String s[] = new String[1];
-
s[0] = "EMPTY";
-
return s;
-
} else {
-
// TODO
-
// System.out.println("model —–" + index);
-
return Queue.printQueueContent(array[index]);
-
}
-
}
-
-
/**
-
* It returns a string containing the parameters of the model such as the
-
* number of queues or clients.
-
*/
-
public String toString() {
-
String s = "";
-
s += "Clients: " + iNumberOfClients + "\n" + "Queues: "
-
+ iMaximumNumberOfQueues + "\n" + "Min Arrival Time: "
-
+ iMinimumArrivalTime + "\n" + "Max Arrival Time: "
-
+ iMaximumArrivalTime + "\n" + "Min Service Time: "
-
+ iMinimumServiceTime + "\n" + "Max Service Time: "
-
+ iMaximumServiceTime + "\n" + "Simulate for: "
-
+ "Simulation time: " + simulationTime + "\n";
-
return s;
-
-
}
-
-
/**
-
* Sets the parameters of the simulations.
-
*
-
* @param numberOfClients -
-
* clients
-
* @param maximumNumberOfQueues -
-
* queues
-
* @param minimumArrivalTime -
-
* minimum arrival time
-
* @param maximumArrivalTime -
-
* maximum arrival time
-
* @param minimumServiceTime -
-
* minimum service time
-
* @param maximumServiceTime -
-
* maximum service time
-
*/
-
public void setSimulationParameters(int numberOfClients,
-
int maximumNumberOfQueues, int minimumArrivalTime,
-
int maximumArrivalTime, int minimumServiceTime,
-
int maximumServiceTime) {
-
-
setNumberOfClients(numberOfClients);
-
setMaximumNumberOfQueues(maximumNumberOfQueues);
-
setServiceTimeLimits(minimumServiceTime, maximumServiceTime);
-
setArrivalTimeLimits(minimumArrivalTime, maximumArrivalTime);
-
array = new QueueADT[maximumNumberOfQueues];
-
queueFinishTime = new int[maximumNumberOfQueues];
-
-
for (int i = 0; i < maximumNumberOfQueues; i++) {
-
queueFinishTime[i] = 0;
-
}
-
for (int i = 0; i < numberOfClients; i++) {
-
PersonInterface p = createPerson(i);
-
personArray.add(p);
-
}
-
-
/*
-
* if (personArray != null) java.util.Collections.sort(personArray);
-
*/
-
}
-
-
/**
-
* It simulates the queue operations
-
*/
-
public void simulate() throws WaitingQueuesException {
-
-
++simulationTime;
-
-
if (simulationTime > 0) {
-
// compute waiting times
-
updateWaitingAndServingTime();
-
for (int i = 0; i < array.length; i++)
-
movingFromThisQueue(i);
-
}
-
-
// add arrived persons into the queue
-
-
if (personArray != null) {
-
boolean found;
-
do {
-
found = false;
-
for (int i = 0; i < personArray.size(); i++) {
-
Object obj = personArray.get(i);
-
if (!(obj instanceof PersonInterface))
-
throw new AssertionError(
-
"The array contains an invalid object, that is not a person");
-
-
PersonInterface p = (PersonInterface) obj;
-
if (p.getArrivalTime() == (simulationTime)) {
-
addPersonToQueue(p);
-
p.incrementWaitingTime(1);
-
totalTime++;
-
// TODO
-
// System.out.println("model *"+p.toString());
-
personArray.remove(i);
-
found = true;
-
break;
-
}
-
// System.out.println("model +"+" "+p.getArrivalTime()+"
-
// "+simulationTime+(p.getArrivalTime() == simulationTime));
-
}
-
} while (found);
-
}
-
-
}
-
-
/**
-
* Resets the model.
-
*/
-
public void reset() {
-
// addMessage("The model has been reset.");
-
if (array != null) {
-
for (int i = 0; i < array.length; i++) {
-
Object obj = array[i];
-
if (obj instanceof QueueADT) {
-
QueueADT q = (QueueADT) obj;
-
q.destroy();
-
q = null;
-
}
-
array[i] = null;
-
}
-
}
-
array = null;
-
if (personArray != null) {
-
for (int i = 0; i < personArray.size(); i++) {
-
Object obj = personArray.get(i);
-
if (obj instanceof QueueADT) {
-
PersonInterface q = (PersonInterface) obj;
-
q.destroy();
-
q = null;
-
}
-
// personArray.remove(i);
-
}
-
personArray.clear();
-
// personArray = new ArrayList();
-
}
-
availableQueues = -1;
-
officeOpened = false;
-
simulationTime = 0;
-
totalTime = 0;
-
nrPersons = 0;
-
}
-
-
/**
-
* Returns a string representation of the average time.
-
*/
-
public String getAverageTime() {
-
double displayTime = averageTime;
-
return "" + displayTime;
-
}
-
-
/**
-
* Returns true if all the persons were served.
-
*/
-
public boolean allPersonsServed() {
-
if (simulationTime <= iMaximumArrivalTime)
-
return false;
-
boolean ok = true;
-
for (int i = 0; i < array.length; i++)
-
if (!array[i].isEmpty())
-
ok = false;
-
return ok;
-
}
-
-
private void setServiceTimeLimits(int minimumServiceTime,
-
int maximumServiceTime) {
-
// precondition
-
if (minimumServiceTime < Constants.MINIMUM_SERVICE_TIME
-
|| minimumServiceTime > Constants.MAXIMUM_SERVICE_TIME
-
|| maximumServiceTime < Constants.MINIMUM_SERVICE_TIME
-
|| maximumServiceTime > Constants.MAXIMUM_SERVICE_TIME
-
|| minimumServiceTime > maximumServiceTime)
-
throw new IllegalArgumentException("Values " + minimumServiceTime
-
+ "," + maximumServiceTime + " violate the precondition");
-
iMinimumServiceTime = minimumServiceTime;
-
iMaximumServiceTime = maximumServiceTime;
-
// postcondition
-
if (minimumServiceTime != iMinimumServiceTime
-
|| maximumServiceTime != iMaximumServiceTime)
-
throw new AssertionError("Values " + minimumServiceTime + ","
-
+ maximumServiceTime + " violate the postcondition");
-
}
-
-
private void setArrivalTimeLimits(int minimumArrivalTime,
-
int maximumArrivalTime) {
-
// precondition
-
if (minimumArrivalTime < Constants.MINIMUM_ARRIVAL_TIME
-
|| minimumArrivalTime > Constants.MAXIMUM_ARRIVAL_TIME
-
|| maximumArrivalTime < Constants.MINIMUM_ARRIVAL_TIME
-
|| maximumArrivalTime > Constants.MAXIMUM_ARRIVAL_TIME
-
|| minimumArrivalTime > maximumArrivalTime)
-
throw new IllegalArgumentException("Values " + minimumArrivalTime
-
+ "," + maximumArrivalTime + " violate the precondition");
-
iMinimumArrivalTime = minimumArrivalTime;
-
iMaximumArrivalTime = maximumArrivalTime;
-
// postcondition
-
if (minimumArrivalTime != iMinimumArrivalTime
-
|| maximumArrivalTime != iMaximumArrivalTime)
-
throw new AssertionError("Values " + minimumArrivalTime + ","
-
+ maximumArrivalTime + " violate the postcondition");
-
}
-
-
private void setNumberOfClients(int numberOfClients) {
-
// precondition
-
if (numberOfClients < Constants.MINIMUM_NUMBER_OF_CLIENTS
-
|| numberOfClients > Constants.MAXIMUM_NUMBER_OF_CLIENTS)
-
throw new IllegalArgumentException("Values " + numberOfClients
-
+ " violate the precondition");
-
-
iNumberOfClients = numberOfClients;
-
// postcondition
-
if (numberOfClients != iNumberOfClients)
-
throw new AssertionError("Values " + iNumberOfClients + ","
-
+ numberOfClients + " violate the postcondition");
-
}
-
-
private void setMaximumNumberOfQueues(int maximumNumberOfQueues) {
-
// precondition
-
if (maximumNumberOfQueues < Constants.MINIMUM_NUMBER_OF_QUEUES
-
|| maximumNumberOfQueues > Constants.MAXIMUM_NUMBER_OF_QUEUES)
-
throw new IllegalArgumentException("Values "
-
+ maximumNumberOfQueues + " violate the precondition");
-
-
iMaximumNumberOfQueues = maximumNumberOfQueues;
-
-
// postcondition
-
if (maximumNumberOfQueues != iMaximumNumberOfQueues)
-
throw new AssertionError("Values " + iNumberOfClients + ","
-
+ maximumNumberOfQueues + " violate the postcondition");
-
}
-
-
/*
-
* private void openNewQueue() { if (availableQueues + 1 >
-
* iMaximumNumberOfQueues) throw new AssertionError( "Maximum number of
-
* queues was reached. No other queues can be openned."); QueueADT queue =
-
* new Queue(); int openedQueue = -1; for (int i = 0; i < availableQueues;
-
* i++) if (array[i] == null) openedQueue = i; if (openedQueue == -1)
-
* openedQueue = ++availableQueues; array[openedQueue] = queue;
-
* addMessage("Opened a new customer queue, the queue number # " +
-
* openedQueue); }
-
*/
-
-
private void openTheOffice() {
-
if (hasTheOfficeOpened())
-
throw new AssertionError("The office has been already openned.");
-
if (!hasTheOfficeOpened()) {
-
// openNewQueue();
-
officeOpened = true;
-
// addMessage("The office has been open");
-
}
-
}
-
-
private void addPersonToQueue(PersonInterface person)
-
throws WaitingQueuesException {
-
// check person
-
if (!hasTheOfficeOpened()) {
-
openTheOffice();
-
}
-
int n;
-
n = optimization(person);
-
if (n == -1)
-
throw new AssertionError("Invalid queue functionning");
-
-
addMessage("Person " + person.getPersonId() + " entered queue #" + n);
-
array[n].enqueue(person);
-
nrPersons++;
-
}
-
-
private void movingFromThisQueue(int queueId) throws WaitingQueuesException {
-
-
if (array[queueId] != null) {
-
Object temp = ((QueueADT) array[queueId]).clone();
-
Object old = ((QueueADT) array[queueId]).clone();
-
-
QueueADT q = (QueueADT) temp;
-
QueueADT temp2 = new Queue();
-
-
PersonInterface person;
-
Object obj = null;
-
if (q.isEmpty()) {
-
return;
-
} else {
-
while (!q.isEmpty()) {
-
try {
-
obj = q.dequeue();
-
if (!q.isEmpty())
-
temp2.enqueue(obj);
-
} catch (WaitingQueuesException e) {
-
e.printStackTrace();
-
}
-
}
-
}
-
if (obj != null) {
-
assert (obj instanceof PersonInterface) : "cast error in model";
-
person = (PersonInterface) obj;
-
array[queueId] = temp2;
-
int n = optimization(person);
-
if (n != queueId) {
-
addMessage("Person " + person.getPersonId()
-
+ "abandonned queue " + queueId + " and entered "
-
+ n);
-
array[n].enqueue(person);
-
} else
-
array[queueId] = (QueueADT) old;
-
-
}
-
}
-
return;
-
-
}
-
-
private int optimization(PersonInterface person) {
-
for (int i = 0; i < array.length; i++)
-
if (array[i] == null)
-
array[i] = new Queue();
-
int min = computeQueueFinishTime(array[0]);
-
int index_min = 0;
-
if (min != 0)
-
for (int i = 1; i < array.length; i++) {
-
int size = computeQueueFinishTime(array[i]);
-
if (size == 0) {
-
min = 0;
-
index_min = i;
-
break;
-
} else if (min > size) {
-
min = size;
-
index_min = i;
-
}
-
}
-
return index_min;
-
}
-
-
private static int computeQueueFinishTime(QueueADT queue) {
-
if (queue == null)
-
return 0;
-
-
QueueADT q = (QueueADT) queue.clone();
-
-
if (q.isEmpty()) {
-
return 0;
-
}
-
-
int n = 0;
-
while (!q.isEmpty()) {
-
try {
-
Object object = q.dequeue();
-
if (!(object instanceof Person))
-
throw new AssertionError(
-
"For some reason the queue returned an invalid object.");
-
Person i = (Person) object;
-
n += i.getServiceTime();
-
n++;
-
} catch (WaitingQueuesException e) {
-
e.printStackTrace();
-
}
-
}
-
if (n == 0) {
-
throw new AssertionError("The queue should not be void");
-
}
-
return n;
-
}
-
-
private static void updateQueueWaitingTime(QueueADT queue) {
-
if (queue == null)
-
return;
-
QueueADT q = queue;
-
QueueADT temp = new Queue();
-
if (q.isEmpty()) {
-
return;
-
}
-
-
while (!q.isEmpty()) {
-
try {
-
Object object = q.dequeue();
-
if (!(object instanceof Person))
-
throw new AssertionError(
-
"For some reason the queue returned an invalid object.");
-
PersonInterface i = (PersonInterface) object;
-
i.incrementWaitingTime(1);
-
totalTime++;
-
temp.enqueue(i);
-
} catch (WaitingQueuesException e) {
-
e.printStackTrace();
-
}
-
}
-
-
while (!temp.isEmpty()) {
-
try {
-
Object object = temp.dequeue();
-
q.enqueue(object);
-
} catch (WaitingQueuesException e) {
-
e.printStackTrace();
-
}
-
}
-
-
temp.destroy();
-
temp = null;
-
-
}
-
-
private static void updateQueueServiceTime(QueueADT queue, int queueId) {
-
if (queue == null)
-
return;
-
QueueADT q = queue;
-
QueueADT temp = new Queue();
-
if (q.isEmpty()) {
-
return;
-
}
-
-
if (!q.isEmpty()) {
-
try {
-
// get the first entry
-
Object object = q.dequeue();
-
if (!(object instanceof Person))
-
throw new AssertionError(
-
"For some reason the queue returned an invalid object.");
-
Person i = (Person) object;
-
i.decrementServiceTime(1);
-
if (i.personWasServed()) {
-
addMessage("Person " + i.getPersonId()
-
+ " was served and exited queue #" + queueId);
-
i.destroy();
-
i = null;
-
} else
-
temp.enqueue(i);
-
} catch (WaitingQueuesException e) {
-
e.printStackTrace();
-
}
-
}
-
-
while (!q.isEmpty()) {
-
try {
-
Object object = q.dequeue();
-
temp.enqueue(object);
-
} catch (WaitingQueuesException e) {
-
e.printStackTrace();
-
}
-
}
-
-
while (!temp.isEmpty()) {
-
try {
-
Object object = temp.dequeue();
-
q.enqueue(object);
-
} catch (WaitingQueuesException e) {
-
e.printStackTrace();
-
}
-
}
-
temp.destroy();
-
temp = null;
-
}
-
-
private void updateWaitingAndServingTime() {
-
for (int i = 0; i < array.length; i++)
-
if (array[i] != null) {
-
updateQueueServiceTime(array[i], i);
-
updateQueueWaitingTime(array[i]);
-
queueFinishTime[i] = computeQueueFinishTime(array[i]);
-
}
-
// System.out.println(" model …. " + totalTime + " " + nrPersons);
-
this.averageTime = totalTime / (1.0 * nrPersons);
-
}
-
-
/*
-
* public int availableOffices() { return availableQueues; }
-
*/
-
-
private static void addMessage(String sMessage) {
-
message += "\n" + sMessage;
-
}
-
-
private PersonInterface createPerson(int id) {
-
int service = randomNumber(iMinimumServiceTime, iMaximumServiceTime);
-
int arrival = randomNumber(iMinimumArrivalTime, iMaximumArrivalTime);
-
PersonInterface p = new Person(id, service, arrival);
-
// TODO
-
//System.out.println(p.toString());
-
return p;
-
}
-
-
private static int randomNumber(int minimumValue, int maximumValue) {
-
if (minimumValue < 0 || maximumValue < 0)
-
throw new IllegalArgumentException("Values " + minimumValue + ","
-
+ maximumValue + " violates the precondition");
-
-
int n;
-
do {
-
n = minimumValue + (int) (Math.random() * maximumValue);
-
} while (n < minimumValue || n > maximumValue);
-
-
if (!(n >= minimumValue || n <= maximumValue))
-
throw new AssertionError("Invalid random number " + n
-
+ " was generated.");
-
return n;
-
-
}
-
-
// private static ArrayList array = null;
-
private static QueueADT[] array;
-
private int queueFinishTime[];
-
private int availableQueues;
-
private int iNumberOfClients;
-
private int iMaximumNumberOfQueues;
-
private int iMinimumArrivalTime;
-
private int iMaximumArrivalTime;
-
private int iMinimumServiceTime;
-
private int iMaximumServiceTime;
-
private static String message;
-
private boolean officeOpened;
-
private int simulationTime;
-
private ArrayList personArray;
-
-
private double averageTime;
-
private static int nrPersons = 0;
-
private static int totalTime = 0;
-
-
}