Something went wrong on our end
ServerWithReneges.java 7.70 KiB
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package mv3302;
import static java.lang.Double.NaN;
import java.util.SortedSet;
import java.util.TreeSet;
import static simkit.Priority.HIGH;
import simkit.SimEntityBase;
import simkit.random.RandomVariate;
/**
* Implementation of the multiple server queue model using<code>Customer</code>
* objects to represent individual customers. This allows the model to
* explicitly tally measures such as delay in queue and time in system.
*/
public final class ServerWithReneges extends SimEntityBase {
/**
* Number of servers (k)
*/
private int totalNumberServers;
/**
* # of available servers (S)
*/
protected int numberAvailableServers;
/**
* Container of waiting customers (q)
*/
protected SortedSet<Customer> queue;
/**
* time a given customer spends in queue (D - a transient state)
*/
protected double delayInQueueServed = NaN;
/**
* time a given customer will spend in the queue before reneging
*/
private double delayInQueueReneged;
/**
* time a given customer spends in the system (W - a transient state)
*/
protected double timeInSystem = NaN;
private int numberReneges;
private int numberServed;
/**
* Generates service times ({t<sub>S</sub>})
*/
private RandomVariate serviceTimeGenerator;
/**
* Instantiate a ServerWithReneges with the given totalNumberServers and
* serviceTimeGenerator. Note: should call <code>this()<</code> to ensure
* that <code>queue</code> is instantiated
*
* @param totalNumberServers
* @param serviceTimeGenerator
*/
public ServerWithReneges(int totalNumberServers, RandomVariate serviceTimeGenerator) {
this();
setTotalNumberServers(totalNumberServers);
setServiceTimeGenerator(serviceTimeGenerator);
}
/**
* Instantiate the <code>queue</code>state variable
*/
public ServerWithReneges() {
this.queue = new TreeSet<>();
}
/**
* Initialize state variables:<ul>
* <li>Empty <code>queue</code>
* <li>set numberAvailableServers to totalNumberServers
* <li>Set numberServed to 0
* <li>Set delayInQueue to NaN
* <li>Set timeInSystem to NaN </ul>
*/
@Override
public void reset() {
super.reset();
queue.clear();
numberAvailableServers = getTotalNumberServers();
delayInQueueServed = NaN;
delayInQueueReneged = 0.0;
timeInSystem = NaN;
numberReneges = 0;
numberServed = 0;
}
/**
* Fire property changes for time-varying states
*/
public void doRun() {
firePropertyChange("queue", getQueue());
firePropertyChange("numberAvailableServers", getNumberAvailableServers());
firePropertyChange("numberReneges", getNumberReneges());
}
/**
* Stamp time and add customer to <code>queue</code><br>
* if available server, schedule StartService with delay of 0.0
*
* @param customer Arriving customer
*/
public void doArrival(Customer customer) {
customer.stampTime();
SortedSet<Customer> oldQueue = getQueue();
queue.add(customer);
firePropertyChange("queue", oldQueue, getQueue());
waitDelay("Renege", 0.0, customer);
if (numberAvailableServers > 0) {
waitDelay("StartService", 0.0, HIGH);
}
}
/**
* Decrement numberAvailableServers<br>
* Remove first customer from <code>queue</code><br>
* Compute delayInQueueServed as elapsed time<br>
* Schedule EndService with delay generated by serviceTimeGenerator
*/
public void doStartService() {
Customer customer = queue.first();
SortedSet<Customer> oldQueue = getQueue();
queue.remove(customer);
firePropertyChange("queue", oldQueue, getQueue());
int oldNumberAvailableServers = getNumberAvailableServers();
numberAvailableServers -= 1;
firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers());
delayInQueueServed = customer.getElapsedTime();
firePropertyChange("delayInQueueServed", getDelayInQueueServed());
interrupt("Renege", customer);
waitDelay("EndService", serviceTimeGenerator, customer);
}
/**
* Remove customer from the queue, increment the numberReneges, fires
* property changes for the total number of reneges, and captures
* delayInQueueReneged values as elapsedTime
*/
public void doRenege(Customer customer) {
delayInQueueReneged = customer.getElapsedTime();
firePropertyChange("delayInQueueReneged", getDelayInQueueReneged());
SortedSet<Customer> oldQueue = getQueue();
queue.remove(customer);
firePropertyChange("queue", oldQueue, getQueue());
double oldNumberReneges = getNumberReneges();
numberReneges += 1;
firePropertyChange("numberReneges", oldNumberReneges, getNumberReneges());
}
/**
* Increment numberAvailableServers<br>
* Compute timeInSystem as customer's elapsedTime<br>
* Increment numberServed<br>
* If customer(s) in <code>queue</code>, schedule StartService with delay of
* 0.0
*
* @param customer Given customer completing service
*/
public void doEndService(Customer customer) {
int oldNumberAvailableServers = getNumberAvailableServers();
numberAvailableServers += 1;
firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers());
timeInSystem = customer.getElapsedTime();
firePropertyChange("timeInSystem", getTimeInSystem());
numberServed += 1;
if (!queue.isEmpty()) {
waitDelay("StartService", 0.0, HIGH);
}
}
/**
* @return the totalNumberServers
*/
public int getTotalNumberServers() {
return totalNumberServers;
}
/**
* @param totalNumberServers the totalNumberServers to set
* @throws IllegalArgumentException if totalNumberServers ≤ 0
*/
public void setTotalNumberServers(int totalNumberServers) {
if (totalNumberServers <= 0) {
throw new IllegalArgumentException("totalNumberServers must be > 0: " + totalNumberServers);
}
this.totalNumberServers = totalNumberServers;
}
/**
* @return the serviceTimeGenerator
*/
public RandomVariate getServiceTimeGenerator() {
return serviceTimeGenerator;
}
/**
* @param serviceTimeGenerator the serviceTimeGenerator to set
*/
public void setServiceTimeGenerator(RandomVariate serviceTimeGenerator) {
this.serviceTimeGenerator = serviceTimeGenerator;
}
/**
* @return the numberAvailableServers
*/
public int getNumberAvailableServers() {
return numberAvailableServers;
}
/**
* @return the queue
*/
public SortedSet<Customer> getQueue() {
return new TreeSet<>(queue);
}
/**
* @return the delayInQueue
*/
public double getDelayInQueueServed() {
return delayInQueueServed;
}
/**
* @return the timeInSystem
*/
public double getTimeInSystem() {
return timeInSystem;
}
/**
* @return the delayInQueueReneged
*/
public double getDelayInQueueReneged() {
return delayInQueueReneged;
}
public double getNumberReneges() {
return numberReneges;
}
/**
* @return the numberServed
*/
public int getNumberServed() {
return numberServed;
}
}