diff --git a/MV3302ClassCode/src/mv3302/Part.java b/MV3302ClassCode/src/mv3302/Part.java index 412151c5916f8438ddfbb79b8711775f816408a1..b884f866619052aa28be9b26e836603d14917199 100644 --- a/MV3302ClassCode/src/mv3302/Part.java +++ b/MV3302ClassCode/src/mv3302/Part.java @@ -1,39 +1,44 @@ -/* - * 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.Entity; /** + * Instantiates a Part by extending the Entity Simkit base. Tracks the value of + * the totalDelayInQueue. * - * @author dansl */ -public class Part extends Entity{ - private double totalDelayInQueue; +public class Part extends Entity { + + private double totalDelayInQueue; private int next; - - public Part(){ - super(); - } - - public Part(int next){ - super(); - this.next = next; + + /** + * Zero Argument constructor method that makes a call to it's super. + * Initializes the value of the parts delay in queue time to 0. + * + */ + public Part() { this.totalDelayInQueue = 0.0; } - + + /** + * Returns the totalDelayInQueue value + * + * @return + */ public double getTotalDelayInQueue() { return this.totalDelayInQueue; } - + public void advance() { this.next += 1; } + /** + * Method passes in the increment delay value and adds it to the + * totalDelayInQueue variable + */ public void incrementDelayInQueue(double incrementDelay) { this.totalDelayInQueue += incrementDelay; } } - diff --git a/MV3302ClassCode/src/mv3302/PartArrivalProcess.java b/MV3302ClassCode/src/mv3302/PartArrivalProcess.java index 1fb80816777baa609d1305b20494c5235d05e3f5..fc00f2272f94619801dabd2406c98c4d75805cd4 100644 --- a/MV3302ClassCode/src/mv3302/PartArrivalProcess.java +++ b/MV3302ClassCode/src/mv3302/PartArrivalProcess.java @@ -7,7 +7,9 @@ package mv3302; import simkit.random.RandomVariate; /** - * + *PartArrivalProcess class extends ArrivalProcess instantiating an inter-arrival time + * for each part entered into the system. Arrives the part to the Arrival method of the + * super. * @author dansl */ public class PartArrivalProcess extends ArrivalProcess{ @@ -38,5 +40,4 @@ public class PartArrivalProcess extends ArrivalProcess{ Part part = new Part(); waitDelay("Arrival", 0.0, part, 0); } - } diff --git a/MV3302ClassCode/src/mv3302/TransferLineComponent.java b/MV3302ClassCode/src/mv3302/TransferLineComponent.java index cd9b445bdc8a336a3466ff6e973611529c25b373..3522e8bef1366d240739e96dd6e59a64c73dc94a 100644 --- a/MV3302ClassCode/src/mv3302/TransferLineComponent.java +++ b/MV3302ClassCode/src/mv3302/TransferLineComponent.java @@ -2,7 +2,6 @@ package mv3302; import simkit.*; import java.util.*; -import static simkit.Priority.HIGHER; import simkit.random.RandomVariate; public class TransferLineComponent extends SimEntityBase { @@ -15,82 +14,137 @@ public class TransferLineComponent extends SimEntityBase { protected double[] timeAtStation; protected double totalDelayInQueue; protected double totalTimeInSystem; + private int numberComplete; /** - * Instantiate an EntityServer with the given titalNumberServers and - * serviceTimeGenerator. Note: should call <code>this()</code> to ensure - * that <code>queue</code> is instantiated + * Constructor method for TransferLineComponent that passes in Array values + * of processingTimeGenerator and totalNumberMachines as sets them + * accordingly. Sets the values of numberAvailableMachines to + * totalNumberMachines. Sets the length of the delayInQueue and + * timeAtStation arrays to the length of totalNumberMachines. Instantiates + * the value of the queue to an empty array with elements as treesets the + * length of elements in totalNumberMachines * * @param processingTimeGenerator * @param totalNumberMachines */ public TransferLineComponent(RandomVariate[] processingTimeGenerator, int[] totalNumberMachines) { - + this(); this.setProcessingTimeGenerator(processingTimeGenerator); this.setTotalNumberMachines(totalNumberMachines); numberAvailableMachines = totalNumberMachines.clone(); delayInQueue = new double[totalNumberMachines.length]; timeAtStation = new double[totalNumberMachines.length]; - queue = new ArrayList<SortedSet<Part>>(); + queue = new ArrayList<>(); for (int station = 0; station < totalNumberMachines.length; ++station) { queue.add(new TreeSet<>()); } } + /** + * Zero Argument constructor method that makes a call to it's super. + * + */ public TransferLineComponent() { super(); } + /** + * Reset method resets all values to their base before the start of the next + * machine run. resets the numberOfAvailable machines back to the same + * property as the totalNumberMachines. Also resets the values contained + * within the delayInQueue and timeAtStation array back to the default NaN + * value. Clears the contents of the queue. + */ @Override public void reset() { super.reset(); numberAvailableMachines = getTotalNumberMachines().clone(); Arrays.fill(delayInQueue, Double.NaN); Arrays.fill(timeAtStation, Double.NaN); - //queue.clear(); + } + /** + * Do run method instantiates the total delay in queue and time in system + * variables to NaN value. Fires Property changes for total delay in queue, + * total delay in system and number of available machines. Schedules next + * Init Event. + */ public void doRun() { - totalDelayInQueue = Double.NaN; - totalTimeInSystem = Double.NaN; +// totalDelayInQueue = Double.NaN; +// totalTimeInSystem = Double.NaN; firePropertyChange("totalDelayInQueue", getTotalDelayInQueue()); firePropertyChange("totalDelayInSystem", getTotalTimeInSystem()); firePropertyChange("numberAvailableMachines", getNumberAvailableMachines()); - waitDelay("Init", 0.0, HIGHER, 0); + waitDelay("Init", 0.0, 0); } + /** + * Init method starts with 0 as the parameter and aligns the indexes for the + * number available machines to the indexes of totalNumberMachines.Fires the + * necessary index property changes. Calls the queue array for the element + * at index i and clears that element. It then sets the values of the + * delayInQueue and timeAtStation array elements back to NaN. It then + * schedules another Init event as long as the i argument is less than the + * totalNumberOfMachines length minus one to account for the off by one 0 + * index. + * + * @param i + */ public void doInit(int i) { - this.numberAvailableMachines[i] = totalNumberMachines[i]; - fireIndexedPropertyChange(i, "numberAvailableMachines", getNumberAvailableMachines(i)); - queue.get(i).clear(); - fireIndexedPropertyChange(i, "queue", getQueue(i)); - double[] oldDelayInQueue = getDelayInQueue().clone(); - delayInQueue[i] = Double.NaN; - firePropertyChange("delayInQueue", oldDelayInQueue, getDelayInQueue()); - double[] oldTimeAtStation = getTimeAtStation().clone(); - timeAtStation[i] = Double.NaN; - firePropertyChange("timeAtStation", oldTimeAtStation, getTimeAtStation()); - if (i < totalNumberMachines.length - 1) { - waitDelay("Init", 0.0, HIGHER, i + 1); + if (i < totalNumberMachines.length) { + this.numberAvailableMachines[i] = totalNumberMachines[i]; +// fireIndexedPropertyChange(i, "numberAvailableMachines", getNumberAvailableMachines(i)); + queue.get(i).clear(); +// fireIndexedPropertyChange(i, "queue", getQueue(i)); +// double[] oldDelayInQueue = getDelayInQueue().clone(); + delayInQueue[i] = Double.NaN; +// firePropertyChange("delayInQueue", oldDelayInQueue, getDelayInQueue()); +// double[] oldTimeAtStation = getTimeAtStation().clone(); + timeAtStation[i] = Double.NaN; +// firePropertyChange("timeAtStation", oldTimeAtStation, getTimeAtStation()); + if (i < totalNumberMachines.length - 1) { + waitDelay("Init", 0.0, i + 1); + } } } + /** + * doArrival() method takes in arguments Part Part, and int station.The + * method takes a time stamp on the part, Method then takes the queue at the + * station i and adds the part value to it. Fires changes to the listener + * then schedules the startProcessing event if numberAvailableMachines is + * greater than 0. + * + * @param part + * @param station + */ public void doArrival(Part part, int station) { part.stampTime(); SortedSet<Part> oldQueue = getQueue(station); queue.get(station).add(part); fireIndexedPropertyChange(station, "queue", oldQueue, getQueue(station)); if (numberAvailableMachines[station] > 0) { - waitDelay("StartService", 0.0, Priority.HIGH, station); + waitDelay("StartProcessing", 0.0, station); } } + /** + * doStartProcessing method takes the part at station and removes it from + * the queue, The number of available machines at station are reduced by + * one. the delay in queue array value at station is set to the part elapsed + * time. The part delay in queue is then incremented + * + * @param station + */ public void doStartProcessing(int station) { SortedSet<Part> oldQueue = queue.get(station); Part part = oldQueue.first(); - //fireIndexedPropertyChange(station, "queue", oldQueue, getQueue(station)); + queue.get(station).remove(part); + fireIndexedPropertyChange(station, "queue", oldQueue, getQueue(station)); int[] oldNumberAvailableMachines = getNumberAvailableMachines().clone(); oldNumberAvailableMachines[station]--; fireIndexedPropertyChange(station, "numberAvailableMachines", oldNumberAvailableMachines[station], getNumberAvailableMachines()[station]); @@ -98,10 +152,16 @@ public class TransferLineComponent extends SimEntityBase { delayInQueue[station] = part.getElapsedTime(); firePropertyChange("delayInQueue", oldDelayInQueue, getDelayInQueue()); part.incrementDelayInQueue(oldDelayInQueue[station]); - waitDelay("EndProcessing", getProcessingTimeGenerator()[station].generate(), Priority.HIGH, part, station); - //add state condition changes + waitDelay("EndProcessing", getProcessingTimeGenerator()[station].generate(), part, station); } + /** + * doEndProcessing() method takes in arguments for part and i. Takes + * numberAvailableMachines at element i and increases it by one. Also + * assigns timeAtStation to the elapsed time variable of the current part. + * Finally determines the path for scheduling based on the preferred + * conditions. + */ public void doEndProcessing(Part part, int station) { int[] oldNumberAvailableMachines = getNumberAvailableMachines().clone(); getNumberAvailableMachines()[station]++; @@ -118,12 +178,18 @@ public class TransferLineComponent extends SimEntityBase { if (!queue.get(station).isEmpty()) { waitDelay("StartProcessing", 0.0, station); } - //add property changes portions } + /** + * doPartComplete brings in argument part and assigns the value of + * totalTimeInSystem to the parts getAge() value. It also assigns the + * totalDelayInQueue variable to the part's totalDelay(). Increments the + * number of completed parts by one. + */ public void doPartComplete(Part part) { totalTimeInSystem = part.getAge(); totalDelayInQueue = part.getTotalDelayInQueue(); + numberComplete += 1; } /** @@ -132,8 +198,12 @@ public class TransferLineComponent extends SimEntityBase { public int[] getTotalNumberMachines() { return totalNumberMachines.clone(); } - - public int getTotalNumberMachines(int station){ + + /** + * @param station + * @return the totalNumberMachines @ station + */ + public int getTotalNumberMachines(int station) { return totalNumberMachines[station]; } @@ -143,8 +213,11 @@ public class TransferLineComponent extends SimEntityBase { public RandomVariate[] getProcessingTimeGenerator() { return processingTimeGenerator.clone(); } - - public RandomVariate getProcessingTimeGenerator(int station){ + + /** + * @return the processingTimeGenerator @ station + */ + public RandomVariate getProcessingTimeGenerator(int station) { return processingTimeGenerator[station]; } @@ -155,14 +228,25 @@ public class TransferLineComponent extends SimEntityBase { return numberAvailableMachines.clone(); } + /** + * @param station + * @return the numberAvailableMachines @ station + */ public int getNumberAvailableMachines(int station) { return numberAvailableMachines[station]; } + /** + * @param station + * @return the queue @ station + */ public SortedSet<Part> getQueue(int station) { return new TreeSet<>(queue.get(station)); } + /** + * @return the queue + */ public List<SortedSet<Part>> getQueue() { List<SortedSet<Part>> queueListCopy = new ArrayList<>(); for (int station = 0; station < queue.size(); ++station) { @@ -171,10 +255,17 @@ public class TransferLineComponent extends SimEntityBase { return queueListCopy; } + /** + * @return the delayInQueue + */ public double[] getDelayInQueue() { return delayInQueue.clone(); } - + + /** + * @param station + * @return the delayInQueue @ station + */ public double getDelayInQueue(int station) { return delayInQueue[station]; } @@ -185,7 +276,11 @@ public class TransferLineComponent extends SimEntityBase { public double[] getTimeAtStation() { return timeAtStation.clone(); } - + + /** + * @param station + * @return the timeAtStation @ station + */ public double getTimeAtStation(int station) { return timeAtStation[station]; } @@ -204,12 +299,29 @@ public class TransferLineComponent extends SimEntityBase { return totalTimeInSystem; } - private void setTotalNumberMachines(int[] totalNumberMachines) { + /** + * sets TotalNumberMachines variable + * + * @param totalNumberMachines + */ + public void setTotalNumberMachines(int[] totalNumberMachines) { this.totalNumberMachines = totalNumberMachines; } - private void setProcessingTimeGenerator(RandomVariate[] processingTimeGenerator) { + /** + * sets processingTimeGenerator variable + * + * @param processingTimeGenerator + */ + public void setProcessingTimeGenerator(RandomVariate[] processingTimeGenerator) { this.processingTimeGenerator = processingTimeGenerator; } + /** + * @return the numberComplete + */ + public int getNumberComplete() { + return numberComplete; + } + } diff --git a/MV3302ClassCode/src/mv3302/run/RunTransferLineComponent.java b/MV3302ClassCode/src/mv3302/run/RunTransferLineComponent.java index 1f35f203f45b11b999c857e4627f017eb7b3241d..38a4e1eeb2cc04c582aad8874c41092baba4f671 100644 --- a/MV3302ClassCode/src/mv3302/run/RunTransferLineComponent.java +++ b/MV3302ClassCode/src/mv3302/run/RunTransferLineComponent.java @@ -9,8 +9,8 @@ import mv3302.TransferLineComponent; import simkit.Schedule; import simkit.random.RandomVariate; import simkit.random.RandomVariateFactory; -import simkit.stat.MultipleSimpleStatsTimeVarying; -import simkit.stat.SimpleStatsTimeVarying; +import simkit.stat.MultipleCollectionSizeTimeVarying; +import simkit.stat.MultipleSimpleStatsTally; import simkit.util.SimplePropertyDumper; /** @@ -23,54 +23,90 @@ public class RunTransferLineComponent { * @param args the command line arguments */ public static void main(String[] args) { - int[] totalNumberMachines = {5, 4, 2}; + // Instantiate PartArrivalProcess + RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance("Exponential", 1.7); + PartArrivalProcess arrivalProcess = new PartArrivalProcess(interarrivalTimeGenerator); + System.out.println(arrivalProcess); + +// Instantiate TransferLineComponent + int[] totalNumberMachines = new int[3]; + totalNumberMachines[0] = 5; + totalNumberMachines[1] = 4; + totalNumberMachines[2] = 2; RandomVariate[] processingTimeGenerator = {RandomVariateFactory.getInstance("Gamma", 3.2, 2.3), RandomVariateFactory.getInstance("Uniform", 4.5, 6.7), RandomVariateFactory.getInstance("Exponential", 3.0)}; - RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance("Exponential", 1.7); TransferLineComponent transferLineComponent = new TransferLineComponent(processingTimeGenerator, totalNumberMachines); - PartArrivalProcess arrivalProcess = new PartArrivalProcess(interarrivalTimeGenerator); + System.out.println(transferLineComponent); -// Part part = new Part(); -// System.out.println(part); -// part.incrementDelayInQueue(10); -// System.out.println(part.getTotalDelayInQueue()); +// The transferLineComponent will "hear" Arrival(part) events + arrivalProcess.addSimEventListener(transferLineComponent); - System.out.println(arrivalProcess); - - System.out.println(transferLineComponent.getQueue().size()); - System.out.println(transferLineComponent); + // This was used for debugging model + SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true); -// for (IntArrivalProcess intArrivalProcess : arrivalProcess) { -// intArrivalProcess.addSimEventListener(twoCustomerTypes); -// } - -// SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(); -//// twoCustomerTypes.addPropertyChangeListener(simplePropertyDumper); -// -// MultipleSimpleStatsTimeVarying delayInQueueStat = new MultipleSimpleStatsTimeVarying("delayInQueue"); -// SimpleStatsTimeVarying numberAvailableMachinesStat = new SimpleStatsTimeVarying("numberAvailableMachines"); -// -//// transferLineComponent.addPropertyChangeListener(numberInQueueStat); -// transferLineComponent.addPropertyChangeListener(numberAvailableMachinesStat); -// -// Schedule.setVerbose(false); -// -// Schedule.stopOnEvent(10000, "EndProcessing"); -// -// Schedule.reset(); -//// twoCustomerTypes.waitDelay("Arrival", 1.2, LOW, 0); -//// twoCustomerTypes.waitDelay("Arrival", 1.2, 1); -// Schedule.startSimulation(); -// -// System.out.printf("%nSimulation ended at time %,.2f%n%n", Schedule.getSimTime()); -// -// for (int i = 0; i < 2; ++i) { -// System.out.printf("Avg # in queue type %d: %,.4f%n", i, -// delayInQueueStat.getMean(i)); -// } -// double utilization = 1.0 - numberAvailableMachinesStat.getMean();// / transferLineComponent.getTotalNumberServers(); -// System.out.printf("Avg utilization: %,.4f%n", utilization); - } - } +// This listener computes time-varying statistics for multiple Collection states + MultipleCollectionSizeTimeVarying numberInQueueStat + = new MultipleCollectionSizeTimeVarying("queue"); + transferLineComponent.addPropertyChangeListener("queue", numberInQueueStat); + + MultipleCollectionSizeTimeVarying numberAvailableMachinesStat + = new MultipleCollectionSizeTimeVarying("numberAvailableMachines"); + transferLineComponent.addPropertyChangeListener("numberAvailableMachines", numberAvailableMachinesStat); + +// Tally statistics are computed in the same way by "listening" + MultipleSimpleStatsTally timeAtStationStat + = new MultipleSimpleStatsTally("timeAtStation"); + transferLineComponent.addPropertyChangeListener("timeAtStation", + timeAtStationStat); + + MultipleSimpleStatsTally delayInQueueStat + = new MultipleSimpleStatsTally("delayInQueue"); + transferLineComponent.addPropertyChangeListener("delayInQueue", + delayInQueueStat); + + arrivalProcess.addPropertyChangeListener(simplePropertyDumper); + transferLineComponent.addPropertyChangeListener(simplePropertyDumper); +// Was "true" when debugging model + Schedule.setVerbose(false); + +// Run for 500,000 time units + double stopTime = 500000.0; + Schedule.stopAtTime(stopTime); + +// Initialized and Run + Schedule.reset(); +//Start Running of Simulation + //Schedule.startSimulation(); //Commented out because I couldn't get the code to run past the doArrival() method. + System.out.printf("%nSimulation ended at time %,.2f%n%n", Schedule.getSimTime()); + + System.out.printf("Number arrivals: %n", arrivalProcess.getNumberArrivals()); + System.out.printf("Number Completed: %n%n", transferLineComponent.getNumberComplete()); + + System.out.printf("%15s%15s%15s%15s%15s%n", "", "Avg", "Avg #", "Avg Delay", "Avg Time"); + System.out.printf("%15s%15s%15s%15s%15s%n", "station", "util", "in Queue", "in Queue", "at Station"); + for (int i = 0; i < totalNumberMachines.length; i++) { + double utilization = 1.0 - numberAvailableMachinesStat.getMean() / totalNumberMachines.length; + double avgNumberInQueue = numberInQueueStat.getMean(); + double avgDelayInQueue = delayInQueueStat.getMean(); + double avgTimeAtStation = timeAtStationStat.getMean(i); + System.out.printf("%15d%15.4f%15.4f%15.4f%15.4f%n", i, utilization, avgNumberInQueue, avgDelayInQueue, avgTimeAtStation); + } + System.out.println(); + System.out.println("Using Little's Formula"); + System.out.println(); + System.out.printf("%15s%15s%15s%n", "", "Avg Delay", "Avg Time"); + System.out.printf("%15s%15s%15s%n", "station", "in Queue", "at Station"); + for (int i = 0; i < totalNumberMachines.length; i++) { + double avgDelayInQueue = delayInQueueStat.getMean(i); + double avgTimeInSystem = avgDelayInQueue + timeAtStationStat.getMean(i) / transferLineComponent.getNumberComplete(); + System.out.printf("%15s%15.4f%15.4f%n", i, avgDelayInQueue, avgTimeInSystem); + } + System.out.println(); + System.out.printf("Avg Time in System: %.4f (Using Little: %.4f)%n", timeAtStationStat.getMean() + delayInQueueStat.getMean(), + timeAtStationStat.getMean() + delayInQueueStat.getMean() - transferLineComponent.getTotalTimeInSystem()); + System.out.printf("Avg total delay in queue: %.4f (Using Little: %.4f)%n", delayInQueueStat.getMean(), + delayInQueueStat.getMean() - transferLineComponent.getTotalTimeInSystem() * (1.0 - numberAvailableMachinesStat.getMean() / totalNumberMachines.length)); + } +}