Skip to content
Snippets Groups Projects
Commit cf796e91 authored by dansl's avatar dansl
Browse files

Commit additions for Steady State and Transient Stats

parent 6de6ab93
No related branches found
No related tags found
No related merge requests found
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Other/File.java to edit this template
*/
/**
*
* @author dansl
*/
public class newJavaFile {
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
// TODO code application logic here
}
}
package mv3302;
import simkit.Entity;
import simkit.random.RandomVariate;
/**
* Instantiates an <code>Entity</code> at each Arrival event and schedules an
* Arrival event with that as its argument
*
* @author ahbuss
*/
public class EntityArrivalProcess extends ArrivalProcess {
/**
* Zero-argument constructor
*/
public EntityArrivalProcess() {
super();
}
/**
* Instantiate an <code>EntityArrivalProcess</code> with the given
* <code>interarrivalTimeGenerator</code>
*
* @param interarrivalTimeGenerator Given
* <code>interarrivalTimeGenerator</code>
*/
public EntityArrivalProcess(RandomVariate interarrivalTimeGenerator) {
super(interarrivalTimeGenerator);
}
/**
* Schedule Arrival(Entity) with a new instance of <code>Entity</code><br>
*/
@Override
public void doArrival() {
super.doArrival();
var entity = new Entity();
waitDelay("Arrival", 0.0, entity);
}
/**
* Does nothing, since this is only to be "heard"
*
* @param entity Given Entity
*/
public void doArrival(Entity entity) {
}
}
package mv3302;
import static java.lang.Double.NaN;
import java.util.SortedSet;
import java.util.TreeSet;
import simkit.Entity;
import static simkit.Priority.HIGH;
import simkit.SimEntityBase;
import simkit.random.RandomVariate;
/**
* Implementation of the multiple server queue model using<code>Entity</code>
* objects to represent individual customers. This allows the model to
* explicitly tally measures such as delay in queue and time in system.
*
* @author ahbuss
*/
public class EntityServer extends SimEntityBase {
/**
* Number of servers (k)
*/
private int totalNumberServers;
/**
* Generates service times ({t<sub>S</sub>})
*/
private RandomVariate serviceTimeGenerator;
/**
* # of available servers (S)
*/
protected int numberAvailableServers;
/**
* Container of waiting customers (q)
*/
protected SortedSet<Entity> queue;
/**
* time a given customer spends in queue (D - a transient state)
*/
protected double delayInQueue;
/**
* time a given customer spends in the system (W - a transient state)
*/
protected double timeInSystem;
/**
* Total number who complete service
*/
protected int numberServed;
/**
* Instantiate an EntityServer with the given titalNumberServers and
* serviceTimeGenerator. Note: should call <code>this()</code> to ensure
* that <code>queue</code> is instantiated
*
* @param totalNumberServers
* @param serviceTimeGenerator
*/
public EntityServer(int totalNumberServers, RandomVariate serviceTimeGenerator) {
this();
setTotalNumberServers(totalNumberServers);
setServiceTimeGenerator(serviceTimeGenerator);
}
/**
* Instantiate the <code>queue</code>state variable
*/
public EntityServer() {
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();
numberServed = 0;
delayInQueue = NaN;
timeInSystem = NaN;
}
/**
* Fire property changes for time-varying states
*/
public void doRun() {
firePropertyChange("queue", getQueue());
firePropertyChange("numberAvailableServers", getNumberAvailableServers());
firePropertyChange("numberServed", getNumberServed());
}
/**
* 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(Entity customer) {
customer.stampTime();
var oldQueue = getQueue();
queue.add(customer);
firePropertyChange("queue", oldQueue, getQueue());
if (numberAvailableServers > 0) {
waitDelay("StartService", 0.0, HIGH);
}
}
/**
* Decrement numbervailableServers<br>
* Remove first customer from <code>queue</code><br>
* Compute delayInQueue as elapsed time<br>
* Schedule EndSrevice with delay generated by serviceTimeGenerator
*/
public void doStartService() {
var oldNumberAvailableServers = getNumberAvailableServers();
numberAvailableServers -= 1;
firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers());
var oldQueue = getQueue();
var customer = queue.first();
queue.remove(customer);
firePropertyChange("queue", oldQueue, getQueue());
delayInQueue = customer.getElapsedTime();
firePropertyChange("delayInQueue", getDelayInQueue());
waitDelay("EndService", serviceTimeGenerator, customer);
}
/**
* 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(Entity customer) {
var oldNumberAvailableServers = getNumberAvailableServers();
numberAvailableServers += 1;
firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers());
timeInSystem = customer.getElapsedTime();
firePropertyChange("timeInSystem", getTimeInSystem());
var oldNumberServed = getNumberServed();
numberServed += 1;
firePropertyChange("numberServed", oldNumberServed, getNumberServed());
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 &le; 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<Entity> getQueue() {
return new TreeSet<>(queue);
}
/**
* @return the numberServed
*/
public int getNumberServed() {
return numberServed;
}
/**
* @return the delayInQueue
*/
public double getDelayInQueue() {
return delayInQueue;
}
/**
* @return the timeInSystem
*/
public double getTimeInSystem() {
return timeInSystem;
}
}
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Beans/Bean.java to edit this template
*/
package mv3302;
import simkit.random.RandomVariate;
/**
*
* @author dansl
*/
public final class StoppedPartArrivalProcess extends PartArrivalProcess {
private RandomVariate interarrivalTimeGenerator;
//int stopTime = 480;
/**
* Zero-argument constructor
*/
public StoppedPartArrivalProcess() {
super();
}
/**
* Instantiate with the given parameters
*
* @param interarrivalTimes Given inter arrival times
*/
public StoppedPartArrivalProcess(RandomVariate interarrivalTimeGenerator) {
setInterarrivalTimeGenerator(interarrivalTimeGenerator);
}
@Override
public void doRun() {
waitDelay("StopArrivals", interarrivalTimeGenerator);
}
/**
* Schedule next Arrival<br>
* Schedule Arrival(index)
*/
public void doStopArrivals() {
interrupt("Arrival");
}
/**
* @return the interarrivalTimeGenerator
*/
@Override
public RandomVariate getInterarrivalTimeGenerator() {
return interarrivalTimeGenerator;
}
/**
* @param interarrivalTimeGenerator the interarrivalTimeGenerator to set
*/
@Override
public void setInterarrivalTimeGenerator(RandomVariate interarrivalTimeGenerator) {
this.interarrivalTimeGenerator = interarrivalTimeGenerator;
}
}
package mv3302;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import simkit.stat.SimpleStatsTally;
/**
*
* @author dansl
*/
public class TransientStats implements PropertyChangeListener {
private final String state;
protected List<SimpleStatsTally> data;
protected int nextObs;
public TransientStats(String state) {
this.state = state;
data = new ArrayList<>();
nextObs = 0;
}
public void reset() {
nextObs = 0;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!evt.getPropertyName().equals(state)) {
return;
}
if (nextObs >= getRawData().size()) {
data.add(new SimpleStatsTally("Data " + nextObs));
}
if (evt.getNewValue() instanceof Number) {
data.get(nextObs).newObservation(((Number)evt.getNewValue()).doubleValue());
}
nextObs += 1;
}
/**
* @return the data
*/
public List<SimpleStatsTally> getRawData() {
return new ArrayList<>(data);
}
}
package mv3302.run;
import static java.lang.Math.sqrt;
import mv3302.PartArrivalProcess;
import mv3302.TransferLineComponent;
import simkit.Schedule;
import simkit.random.RandomVariate;
import simkit.random.RandomVariateFactory;
import simkit.stat.SimpleStatsTally;
import simkit.stat.StudentT;
import simkit.stat.TruncatingSimpleStatsTally;
/**
*
* @author dansl
*/
public class RunSteadyStateAnalysis {
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance(
"Exponential", 2.5);
PartArrivalProcess arrivalProcess = new PartArrivalProcess(interarrivalTimeGenerator);
RandomVariate[] processingTimeGenerator =
{RandomVariateFactory.getInstance("Exponential", 2.4), RandomVariateFactory.getInstance("Gamma", 3.2, 3.3), RandomVariateFactory.getInstance("Uniform", 4.5, 6.7), RandomVariateFactory.getInstance("Exponential", 3.0)};
int[] totalNumberWorkstations = new int[4];
totalNumberWorkstations[0] = 1;
totalNumberWorkstations[1] = 5;
totalNumberWorkstations[2] = 4;
totalNumberWorkstations[3] = 2;
TransferLineComponent transferLineComponent = new TransferLineComponent(processingTimeGenerator, totalNumberWorkstations);
arrivalProcess.addSimEventListener(transferLineComponent);
int warmup = 1000;
int observations = 10000;
SimpleStatsTally delayInQueueStat = new TruncatingSimpleStatsTally("delayInQueue", 2000);
transferLineComponent.addPropertyChangeListener(delayInQueueStat);
System.out.println(arrivalProcess);
System.out.println(transferLineComponent);
SimpleStatsTally outerDelayInQueueStat = new SimpleStatsTally("outerDelayInQueue");
Schedule.stopOnEvent(warmup + observations, "Arrival");
int numberReplications = 15;
double alpha = 0.05;
System.out.println("Avg Delay In Queue");
for (int replication = 1; replication <= numberReplications; ++replication) {
Schedule.reset();
delayInQueueStat.reset();
Schedule.startSimulation();
outerDelayInQueueStat.newObservation(delayInQueueStat.getMean());
System.out.printf("%d %.3f ± %.3f%n",
replication,
outerDelayInQueueStat.getMean(),
outerDelayInQueueStat.getStandardDeviation()
* StudentT.getQuantile(1.0 - 0.5 * alpha, outerDelayInQueueStat.getCount() - 1) / sqrt(outerDelayInQueueStat.getCount())
);
}
}
}
\ No newline at end of file
package mv3302.run;
import static java.lang.Math.sqrt;
import mv3302.StoppedPartArrivalProcess;
import mv3302.TransferLineComponent;
import mv3302.TransientStats;
import simkit.Schedule;
import simkit.random.RandomVariate;
import simkit.random.RandomVariateFactory;
import simkit.stat.SimpleStatsTally;
import simkit.stat.StudentT;
/**
*
* @author dansl
*/
public class RunTransientAnalysis {
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance(
"Exponential", 2.5);
StoppedPartArrivalProcess arrivalProcess = new StoppedPartArrivalProcess(interarrivalTimeGenerator);
RandomVariate[] processingTimeGenerator
= {RandomVariateFactory.getInstance("Exponential", 2.4), RandomVariateFactory.getInstance("Gamma", 3.2, 3.3), RandomVariateFactory.getInstance("Uniform", 4.5, 6.7), RandomVariateFactory.getInstance("Exponential", 3.0)};
int[] totalNumberWorkstations = new int[4];
totalNumberWorkstations[0] = 1;
totalNumberWorkstations[1] = 5;
totalNumberWorkstations[2] = 4;
totalNumberWorkstations[3] = 2;
TransferLineComponent transferLineComponent = new TransferLineComponent(processingTimeGenerator, totalNumberWorkstations);
arrivalProcess.addSimEventListener(transferLineComponent);
TransientStats delayInQueueTransient = new TransientStats("delayInQueue");
SimpleStatsTally delayInQueueStat = new SimpleStatsTally("delayInQueue");
transferLineComponent.addPropertyChangeListener(delayInQueueTransient);
System.out.println(arrivalProcess);
System.out.println(transferLineComponent);
SimpleStatsTally outerDelayInQueueStat = new SimpleStatsTally("outerDelayInQueue");
int stopTime = 50;
double alpha = 0.05;
Schedule.stopOnEvent(stopTime, "Arrival");
System.out.println("Avg Delay In Queue");
for (int replication = 1; replication <= stopTime; ++replication) {
Schedule.reset();
delayInQueueTransient.reset();
Schedule.startSimulation();
outerDelayInQueueStat.newObservation(delayInQueueStat.getMean());
System.out.printf("%d %.3f ± %.3f%n",
replication,
outerDelayInQueueStat.getMean(),
outerDelayInQueueStat.getStandardDeviation()
* StudentT.getQuantile(1.0 - 0.5 * alpha, outerDelayInQueueStat.getCount() - 1) / sqrt(outerDelayInQueueStat.getCount())
);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment