diff --git a/MV3302ClassCode/build.xml b/MV3302ClassCode/build.xml index ca84e3ccdf7ba96f20a167fa1ae47b4adf51e59e..4b6b0b8e4389d7b08cf0dd93ad45804cacaab227 100644 --- a/MV3302ClassCode/build.xml +++ b/MV3302ClassCode/build.xml @@ -7,8 +7,8 @@ <!-- the Compile on Save feature is turned off for the project. --> <!-- You can turn off the Compile on Save (or Deploy on Save) setting --> <!-- in the project's Project Properties dialog box.--> -<project name="MV3302ClassCode" default="default" basedir="."> - <description>Builds, tests, and runs the project MV3302ClassCode.</description> +<project name="MV3302" default="default" basedir="."> + <description>Builds, tests, and runs the project MV3302.</description> <import file="nbproject/build-impl.xml"/> <!-- @@ -58,7 +58,7 @@ An example of overriding the target for project execution could look like this: - <target name="run" depends="MV3302ClassCode-impl.jar"> + <target name="run" depends="MV3302-impl.jar"> <exec dir="bin" executable="launcher.exe"> <arg file="${dist.jar}"/> </exec> diff --git a/MV3302ClassCode/nbproject/build-impl.xml b/MV3302ClassCode/nbproject/build-impl.xml index 9d4e7d2ddb5e48bcf8b549553e167441052adbe6..90f7b24ef66c88a0406e6caf7138a2f4703d0089 100644 --- a/MV3302ClassCode/nbproject/build-impl.xml +++ b/MV3302ClassCode/nbproject/build-impl.xml @@ -19,7 +19,7 @@ is divided into following sections: - cleanup --> -<project xmlns:if="ant:if" xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" xmlns:unless="ant:unless" basedir=".." default="default" name="MV3302ClassCode-impl"> +<project xmlns:if="ant:if" xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" xmlns:unless="ant:unless" basedir=".." default="default" name="MV3302-impl"> <fail message="Please build using Ant 1.8.0 or higher."> <condition> <not> @@ -644,7 +644,7 @@ is divided into following sections: </fileset> </union> <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/> - <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="MV3302ClassCode" testname="TestNG tests" workingDir="${work.dir}"> + <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="MV3302" testname="TestNG tests" workingDir="${work.dir}"> <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/> <propertyset> <propertyref prefix="test-sys-prop."/> @@ -741,7 +741,7 @@ is divided into following sections: <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}"> <isset property="test.method"/> </condition> - <condition else="-suitename MV3302ClassCode -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}"> + <condition else="-suitename MV3302 -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}"> <matches pattern=".*\.xml" string="@{testClass}"/> </condition> <delete dir="${build.test.results.dir}" quiet="true"/> @@ -1082,7 +1082,7 @@ is divided into following sections: <delete file="${built-jar.properties}" quiet="true"/> </target> <target if="already.built.jar.${basedir}" name="-warn-already-built-jar"> - <echo level="warn" message="Cycle detected: MV3302ClassCode was already built"/> + <echo level="warn" message="Cycle detected: MV3302 was already built"/> </target> <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps"> <mkdir dir="${build.dir}"/> @@ -1753,7 +1753,7 @@ is divided into following sections: <delete file="${built-clean.properties}" quiet="true"/> </target> <target if="already.built.clean.${basedir}" name="-warn-already-built-clean"> - <echo level="warn" message="Cycle detected: MV3302ClassCode was already built"/> + <echo level="warn" message="Cycle detected: MV3302 was already built"/> </target> <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps"> <mkdir dir="${build.dir}"/> diff --git a/MV3302ClassCode/nbproject/genfiles.properties b/MV3302ClassCode/nbproject/genfiles.properties index 785d608e70784cd524223b10f13c98a5dc2767ff..6b0ee15ced3b9b6e2359b799876539ae9ae9b6b0 100644 --- a/MV3302ClassCode/nbproject/genfiles.properties +++ b/MV3302ClassCode/nbproject/genfiles.properties @@ -1,8 +1,8 @@ -build.xml.data.CRC32=1f44a756 -build.xml.script.CRC32=0121353d +build.xml.data.CRC32=78ca9dc9 +build.xml.script.CRC32=ca561466 build.xml.stylesheet.CRC32=f85dc8f2@1.104.0.48 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=1f44a756 -nbproject/build-impl.xml.script.CRC32=6aebe263 +nbproject/build-impl.xml.data.CRC32=78ca9dc9 +nbproject/build-impl.xml.script.CRC32=69aa2bcf nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.104.0.48 diff --git a/MV3302ClassCode/nbproject/project.properties b/MV3302ClassCode/nbproject/project.properties index 8952b90118aeb309e5bebcde116ac90d83a2e4e0..8e152217fb8171e32c5ff2f261f011adfce1108e 100644 --- a/MV3302ClassCode/nbproject/project.properties +++ b/MV3302ClassCode/nbproject/project.properties @@ -3,7 +3,7 @@ annotation.processing.enabled.in.editor=false annotation.processing.processors.list= annotation.processing.run.all.processors=true annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output -application.title=MV3302ClassCode +application.title=MV3302 application.vendor=dansl build.classes.dir=${build.dir}/classes build.classes.excludes=**/*.java,**/*.form @@ -29,10 +29,10 @@ debug.test.modulepath=\ dist.archive.excludes= # This directory is removed when the project is cleaned: dist.dir=dist -dist.jar=${dist.dir}/MV3302ClassCode.jar +dist.jar=${dist.dir}/MV3302.jar dist.javadoc.dir=${dist.dir}/javadoc dist.jlink.dir=${dist.dir}/jlink -dist.jlink.output=${dist.jlink.dir}/MV3302ClassCode +dist.jlink.output=${dist.jlink.dir}/MV3302 endorsed.classpath= excludes= includes=** @@ -73,7 +73,8 @@ jlink.additionalmodules= # The jlink additional command line parameters jlink.additionalparam= jlink.launcher=true -jlink.launcher.name=MV3302ClassCode +jlink.launcher.name=MV3302 +main.class=mv3302.run.RunSimpleServer meta.inf.dir=${src.dir}/META-INF mkdist.disabled=true platform.active=default_platform diff --git a/MV3302ClassCode/nbproject/project.xml b/MV3302ClassCode/nbproject/project.xml index f69bcee5b99bc7e52e1f04faf2aaa2daba665a07..ada7c5b8f694760a85fd4af7350fe700b2157be9 100644 --- a/MV3302ClassCode/nbproject/project.xml +++ b/MV3302ClassCode/nbproject/project.xml @@ -3,7 +3,7 @@ <type>org.netbeans.modules.java.j2seproject</type> <configuration> <data xmlns="http://www.netbeans.org/ns/j2se-project/3"> - <name>MV3302ClassCode</name> + <name>MV3302</name> <source-roots> <root id="src.dir"/> </source-roots> diff --git a/MV3302ClassCode/src/mv3302/ArrivalProcess.java b/MV3302ClassCode/src/mv3302/ArrivalProcess.java index c71823627c839a7e220fe5c2726c8254009cd0fe..e17c72d3abacf78bd2e144d9af69ccfd4fe64e36 100644 --- a/MV3302ClassCode/src/mv3302/ArrivalProcess.java +++ b/MV3302ClassCode/src/mv3302/ArrivalProcess.java @@ -1,59 +1,45 @@ -/* - * 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 simkit.SimEntityBase; import simkit.random.RandomVariate; /** - * Program simulates an entity arrival process to collect observations. The - * processing times are generated through the random variate method properties. + * A simple (yet useful) simulation component that schedules Arrival events + * using a <code>RandomVariate</code> instance for the times between Arrival + * events.<br> + * The state <code>numberArrivals></code> is incremented at each Arrival event. * - * @author dansl + * @author ahbuss */ public class ArrivalProcess extends SimEntityBase { /** - * Instantiates the random variable generator to assign arrival time delays - * and total number of arrivals + * Generates interarrival times */ private RandomVariate interarrivalTimeGenerator; - private int numberArrivals; - - /** - * Constructor method that creates unique arrival times when called - * - * @param interarrivalTimeGenerator - */ - public ArrivalProcess(RandomVariate interarrivalTimeGenerator) { - this.setInterarrivalTimeGenerator(interarrivalTimeGenerator); - } /** - * @return the numberArrivals + * The number of arrivals at any given (sim) time */ - public int getNumberArrivals() { - return numberArrivals; - } + protected int numberArrivals; /** - * @return the interarrivalTimeGenerator + * Zero-argument constructor */ - public RandomVariate getInterarrivalTimeGenerator() { - return interarrivalTimeGenerator; + public ArrivalProcess() { } /** - * @param interarrivalTimeGenerator the interarrivalTimeGenerator to set + * Instantiate an Arrival Process with the given interarrivalTimeGenerator + * + * @param interarrivalTimeGenerator Given interarrivalTimeGenerator */ - private void setInterarrivalTimeGenerator(RandomVariate interarrivalTimeGenerator) { - this.interarrivalTimeGenerator = interarrivalTimeGenerator; + public ArrivalProcess(RandomVariate interarrivalTimeGenerator) { + setInterarrivalTimeGenerator(interarrivalTimeGenerator); } /** - * Resets the ArrivalProcess to starting state + * Initialize numberArrivals to 0 */ @Override public void reset() { @@ -62,7 +48,7 @@ public class ArrivalProcess extends SimEntityBase { } /** - * Initializes the run event and schedules subsequent events + * Schedule first Arrival event with delay of interarrival time */ public void doRun() { firePropertyChange("numberArrivals", getNumberArrivals()); @@ -70,14 +56,36 @@ public class ArrivalProcess extends SimEntityBase { } /** - * Creates an arrival event, alters the total number of arrivals and - * schedules the next event + * Increment numberArrivals<br> + * Schedule next Arrival event with delay of interarrival time */ public void doArrival() { int oldNumberArrivals = getNumberArrivals(); - numberArrivals = numberArrivals + 1; + numberArrivals += 1; firePropertyChange("numberArrivals", oldNumberArrivals, getNumberArrivals()); + waitDelay("Arrival", interarrivalTimeGenerator); } + /** + * @return the interarrivalTimeGenerator + */ + public RandomVariate getInterarrivalTimeGenerator() { + return interarrivalTimeGenerator; + } + + /** + * @param interarrivalTimeGenerator the interarrivalTimeGenerator to set + */ + public void setInterarrivalTimeGenerator(RandomVariate interarrivalTimeGenerator) { + this.interarrivalTimeGenerator = interarrivalTimeGenerator; + } + + /** + * @return the numberArrivals + */ + public int getNumberArrivals() { + return numberArrivals; + } + } diff --git a/MV3302ClassCode/src/mv3302/SimpleServer.java b/MV3302ClassCode/src/mv3302/SimpleServer.java new file mode 100644 index 0000000000000000000000000000000000000000..318b1a4e348aa1ee751f4e056877d83dbeeb285e --- /dev/null +++ b/MV3302ClassCode/src/mv3302/SimpleServer.java @@ -0,0 +1,170 @@ +package mv3302; + +import simkit.Priority; +import simkit.SimEntityBase; +import simkit.random.RandomVariate; + +/** + * Class that simulates a simple server by extending SimEntityBase + * + * @author dansl + */ +public class SimpleServer extends SimEntityBase { + + // Instance variables to hold the changing states during the simulation + protected int numberInQueue; + protected int numberAvailableServers; + protected int numberServed; + // Instance variables that hold the build settings of the simulation + private int totalNumberServers; + private RandomVariate serviceTimeGenerator; + + /** + * Constructor method for the SimpleServer class; initializes the number of + * servers and service times for the simulation + * + * @param numberServers + * @param serviceTime + */ + public SimpleServer(int numberServers, RandomVariate serviceTime) { + totalNumberServers = numberServers; + serviceTimeGenerator = serviceTime; + } + + /** + * Getter method for number of customers in the queue + * + * @return the numberInQueue + */ + public int getNumberInQueue() { + return numberInQueue; + } + + /** + * Getter method for the number of servers available in the simulation + * + * @return the numberAvailableServers + */ + public int getNumberAvailableServers() { + return numberAvailableServers; + } + + /** + * Getter method returns the total number of customers complete through the + * processing process + * + * @return the numberServed + */ + public int getNumberServed() { + return numberServed; + } + + /** + * Getter method that returns the total number of servers in the simulation + * + * @return the totalNumberServers + */ + public int getTotalNumberServers() { + return totalNumberServers; + } + + /** + * Setter method sets the total number of servers the simulation will use + * + * @param totalNumberServers + * @throws IllegalArgumentException if totalNumberServers <= 0 @ param + * totalNumberServers the totalNumberServers + */ + public void setTotalNumberServers(int totalNumberServers) { + if (totalNumberServers <= 0) { + throw new IllegalArgumentException("totalNumberServers must be > 0: " + + totalNumberServers); + } + this.totalNumberServers = totalNumberServers; + } + + /** + * Getter method that returns a service time value + * + * @return the serviceTimeGenerator + */ + public RandomVariate getServiceTimeGenerator() { + return serviceTimeGenerator; + } + + /** + * setter method that sets a service time value + * + * @param serviceTimeGenerator the serviceTimeGenerator to set + */ + public void setServiceTimeGenerator(RandomVariate serviceTimeGenerator) { + this.serviceTimeGenerator = serviceTimeGenerator; + } + + /** + * Reset method that returns the simulation to it's original state + */ + @Override + public void reset() { + super.reset(); + numberInQueue = 0; + numberAvailableServers = totalNumberServers; + numberServed = 0; + } + + /** + * Run method fires the state changes to update the listeners + */ + public void doRun() { + firePropertyChange("numberInQueue", getNumberInQueue()); + firePropertyChange("numberAvailableServers", getNumberAvailableServers()); + firePropertyChange("numberServed", getNumberServed()); + } + + /** + * Creates an arrival event, alters the total number of arrivals and + * schedules the next event + */ + public void doArrival() { + int oldNumberInQueue = getNumberInQueue(); + numberInQueue = numberInQueue + 1; + firePropertyChange("numberInQueue", oldNumberInQueue, getNumberInQueue()); + + if (getNumberAvailableServers() > 0) { + waitDelay("StartService", 0.0, Priority.HIGH); + } + } + + /** + * Method decreases the number of customers waiting in the queue and the + * number of available servers. Method then fires those changes for the + * listeners then schedules the EndService + */ + public void doStartService() { + int oldNumberInQueue = getNumberInQueue(); + int oldNumberAvailableServers = getNumberAvailableServers(); + numberAvailableServers = numberAvailableServers - 1; + numberInQueue = numberInQueue - 1; + firePropertyChange("numberInQueue", oldNumberInQueue, getNumberInQueue()); + firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers()); + waitDelay("EndService", getServiceTimeGenerator()); + } + + /** + * Method increases the number of customers that have been served and the + * number of available servers. Method then fires those changes for the + * listeners and schedules the StartService as long as the queue is greater + * than one. + */ + public void doEndService() { + int oldNumberAvailableServers = getNumberAvailableServers(); + numberAvailableServers = numberAvailableServers + 1; + int oldNumberServed = getNumberServed(); + numberServed = numberServed + 1; + firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers()); + firePropertyChange("numberServed", oldNumberServed, getNumberServed()); + if (getNumberInQueue() > 0) { + waitDelay("StartService", 0.0, Priority.HIGH); + } + } +} diff --git a/MV3302ClassCode/src/mv3302/run/RunSimpleServer.java b/MV3302ClassCode/src/mv3302/run/RunSimpleServer.java new file mode 100644 index 0000000000000000000000000000000000000000..5e3a4b0c107406aaf9b0fae437f834af82f38c28 --- /dev/null +++ b/MV3302ClassCode/src/mv3302/run/RunSimpleServer.java @@ -0,0 +1,63 @@ +package mv3302.run; + +import mv3302.ArrivalProcess; +import mv3302.SimpleServer; +import simkit.Schedule; +import simkit.random.RandomVariate; +import simkit.random.RandomVariateFactory; +import simkit.stat.SimpleStatsTimeVarying; + +/** + * + * @author dansl + */ +public class RunSimpleServer { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + //Creates a random variate and assigns that value to the interarrival time variable + RandomVariate interarrivalTime = RandomVariateFactory.getInstance("Uniform", 0.9, 2.2); + //Creates an instance variable of the arrival process + ArrivalProcess arrivalProcess = new ArrivalProcess(interarrivalTime); + //Prints out pertinent information about the arrival process in the sim + System.out.println(arrivalProcess); + + //Creates a random variate with the following properties + String rvName = "Gamma"; + double alpha = 1.7; + double beta = 1.8; + RandomVariate serviceTime = RandomVariateFactory.getInstance(rvName, alpha, beta); + + //Creates a simple server with two servers and varying service times + SimpleServer simpleServer = new SimpleServer(2, serviceTime); + //Prints pertinent simple server details + System.out.println(simpleServer); + //Adds a sim event listener on the simple server for changes in the arrival process + arrivalProcess.addSimEventListener(simpleServer); + + //Creates statistics tracking stats of pertinent variable changes in the simulation over time + SimpleStatsTimeVarying numberInQueueStat = new SimpleStatsTimeVarying("numberInQueue"); + SimpleStatsTimeVarying numberAvailableServersStat = new SimpleStatsTimeVarying("numberAvailableServers"); + + //Sets statistics objects as listeners to state changes in the simple server + simpleServer.addPropertyChangeListener(numberInQueueStat); + simpleServer.addPropertyChangeListener(numberAvailableServersStat); + //Display each event & the Event List if value is set to true + Schedule.setVerbose(false); + //End at the given simulation time + Schedule.stopAtTime(100000.0); + //Invoke reset() on the Simkit component(s) + Schedule.reset(); + //Execute the simulation + Schedule.startSimulation(); + + //Prints out final simulation statistics by pulling necessary values + System.out.printf("Simulation ended at time %,.3f%n", Schedule.getSimTime()); + System.out.printf("%nThere have been %d arrivals%n", arrivalProcess.getNumberArrivals()); + System.out.printf("There have been %d customers served%n", simpleServer.getNumberServed()); + System.out.printf("Average number in queue\t%.3f%n", numberInQueueStat.getMean()); + System.out.printf("Average utilization\t%.3f%n", 1.0 - numberAvailableServersStat.getMean() / simpleServer.getTotalNumberServers()); + } +}