package nl.tudelft.simulation.examples.dsol.mm1queue; import java.io.Serializable; import org.djutils.stats.summarizers.event.StatisticsEvents; import nl.tudelft.simulation.dsol.SimRuntimeException; import nl.tudelft.simulation.dsol.formalisms.Resource; import nl.tudelft.simulation.dsol.formalisms.flow.Delay; import nl.tudelft.simulation.dsol.formalisms.flow.Generator; import nl.tudelft.simulation.dsol.formalisms.flow.StationInterface; import nl.tudelft.simulation.dsol.model.AbstractDSOLModel; import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterDouble; import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterException; import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterInteger; import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterMap; import nl.tudelft.simulation.dsol.simtime.SimTimeDouble; import nl.tudelft.simulation.dsol.simtime.dist.DistContinuousSimTime; import nl.tudelft.simulation.dsol.simtime.dist.DistContinuousSimulationTime; import nl.tudelft.simulation.dsol.simulators.DEVSSimulator; import nl.tudelft.simulation.dsol.statistics.SimCounter; import nl.tudelft.simulation.dsol.statistics.SimPersistent; import nl.tudelft.simulation.dsol.swing.charts.boxAndWhisker.BoxAndWhiskerChart; import nl.tudelft.simulation.dsol.swing.charts.histogram.Histogram; import nl.tudelft.simulation.dsol.swing.charts.xy.XYChart; import nl.tudelft.simulation.jstats.distributions.DistConstant; import nl.tudelft.simulation.jstats.distributions.DistDiscrete; import nl.tudelft.simulation.jstats.distributions.DistDiscreteConstant; import nl.tudelft.simulation.jstats.distributions.DistExponential; import nl.tudelft.simulation.jstats.streams.StreamInterface; /** * The M/M/1 example as published in Simulation Modeling and Analysis by A.M. Law & W.D. Kelton section 1.4 and 2.4. . *

* Copyright (c) 2003-2022 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See * for project information https://simulation.tudelft.nl. The DSOL * project is distributed under a three-clause BSD-style license, which can be found at * * https://simulation.tudelft.nl/dsol/3.0/license.html. *

* @author Peter Jacobs */ public class MM1QueueModel extends AbstractDSOLModel.TimeDouble { /** The default serial version UID for serializable classes. */ private static final long serialVersionUID = 1L; /** the chart for the service time. */ @SuppressWarnings("checkstyle:visibilitymodifier") protected XYChart serviceTimeChart; /** the Box-and-Whisher chart for the service time. */ @SuppressWarnings("checkstyle:visibilitymodifier") protected BoxAndWhiskerChart serviceTimeBWChart; /** * constructor for the MM1Queue. * @param simulator DEVSSimulator.TimeDouble; the simulator * @throws InputParameterException on parameter error */ public MM1QueueModel(final DEVSSimulator.TimeDouble simulator) throws InputParameterException { super(simulator); InputParameterMap generatorMap = new InputParameterMap("generator", "Generator", "Generator", 1.0); generatorMap.add(new InputParameterDouble("intervalTime", "Average interval time", "Average interval time", 1.0, 1.0)); generatorMap.add(new InputParameterDouble("startTime", "Generator start time", "Generator start time", 0.0, 2.0)); generatorMap.add(new InputParameterInteger("batchSize", "Batch size", "batch size", 1, 3.0)); this.inputParameterMap.add(generatorMap); InputParameterMap resourceMap = new InputParameterMap("resource", "Resource", "Resource", 2.0); resourceMap.add(new InputParameterDouble("capacity", "Resource capacity", "Resource capacity", 1.0, 1.0)); resourceMap.add(new InputParameterDouble("serviceTime", "Average service time", "Average service time", 0.8, 2.0)); this.inputParameterMap.add(resourceMap); } /** {@inheritDoc} */ @Override public void constructModel() throws SimRuntimeException { StreamInterface defaultStream = getStream("default"); try { InputParameterMap parameters = this.simulator.getModel().getInputParameterMap(); // The Generator Generator.TimeDouble generator = new Generator.TimeDouble("Generator", this.simulator, Customer.class, null); DistContinuousSimulationTime.TimeDouble intervalTime = new DistContinuousSimulationTime.TimeDouble( new DistExponential(defaultStream, (Double) parameters.get("generator.intervalTime").getCalculatedValue())); generator.setInterval(intervalTime); DistContinuousSimTime.TimeDouble startTime = new DistContinuousSimTime.TimeDouble( new DistConstant(defaultStream, (Double) parameters.get("generator.startTime").getCalculatedValue())); generator.setStartTime(startTime); DistDiscrete batchSize = new DistDiscreteConstant(defaultStream, (Integer) parameters.get("generator.batchSize").getCalculatedValue()); generator.setBatchSize(batchSize); // The queue, the resource and the release double capacity = (Double) parameters.get("resource.capacity").getCalculatedValue(); Resource resource = new Resource<>(this.simulator, capacity); // created a resource StationInterface.TimeDouble queue = new Seize("Seize", this.simulator, resource); StationInterface.TimeDouble release = new Release("Release", this.simulator, resource, capacity); // The server DistContinuousSimulationTime.TimeDouble serviceTime = new DistContinuousSimulationTime.TimeDouble( new DistExponential(defaultStream, (Double) parameters.get("resource.serviceTime").getCalculatedValue())); StationInterface.TimeDouble server = new Delay.TimeDouble("Delay", this.simulator, serviceTime); // The flow generator.setDestination(queue); queue.setDestination(server); server.setDestination(release); // Statistics new SimCounter("counting the generator", this.simulator, generator, Generator.CREATE_EVENT); SimPersistent.TimeDouble persistent = new SimPersistent.TimeDouble("persistent on service time", this.simulator, release, Release.SERVICE_TIME_EVENT); Histogram histogram = new Histogram(this.simulator, "histogram on service time", new double[] {0, 10}, 30); histogram.add("histogram on service time", persistent, StatisticsEvents.SAMPLE_MEAN_EVENT); this.serviceTimeChart = new XYChart(this.simulator, "XY chart of service time", new double[] {0, this.simulator.getReplication().getRunLength()}, new double[] {-2, 30}); this.serviceTimeChart.add(persistent); this.serviceTimeBWChart = new BoxAndWhiskerChart(this.simulator, "BoxAndWhisker on serviceTime"); this.serviceTimeBWChart.add(persistent); } catch (Exception exception) { throw new SimRuntimeException(exception); } } /** {@inheritDoc} */ @Override public Serializable getSourceId() { return "MM1QueueModel"; } }