From b0b430452e45142320055848dec09df44617c6d5 Mon Sep 17 00:00:00 2001
From: brutzman <brutzman@nps.edu>
Date: Sun, 5 Jun 2022 10:43:39 -0700
Subject: [PATCH] initial refactor copy without change, initial test sat

---
 .../TwoCraneBerthsOpenDis7.java               | 242 ++++++++++++++++++
 .../run/RunTwoCranesBerthOpenDis7.java        |  86 +++++++
 .../run/RunTwoCranesBerthOpenDis7Log.txt      |  23 ++
 3 files changed, 351 insertions(+)
 create mode 100644 examples/src/SimkitOpenDis7Examples/TwoCraneBerthsOpenDis7.java
 create mode 100644 examples/src/SimkitOpenDis7Examples/run/RunTwoCranesBerthOpenDis7.java
 create mode 100644 examples/src/SimkitOpenDis7Examples/run/RunTwoCranesBerthOpenDis7Log.txt

diff --git a/examples/src/SimkitOpenDis7Examples/TwoCraneBerthsOpenDis7.java b/examples/src/SimkitOpenDis7Examples/TwoCraneBerthsOpenDis7.java
new file mode 100644
index 0000000000..256c4d7352
--- /dev/null
+++ b/examples/src/SimkitOpenDis7Examples/TwoCraneBerthsOpenDis7.java
@@ -0,0 +1,242 @@
+package SimkitOpenDis7Examples;
+
+import java.util.SortedSet;
+import java.util.TreeSet;
+import simkit.Priority;
+import simkit.SimEntityBase;
+
+/**
+ * @author ahbuss
+ */
+public class TwoCraneBerthsOpenDis7 extends SimEntityBase {
+
+    /**
+     * Queue of Ships waiting to go into the berth
+     */
+    protected SortedSet<Ship> queue;
+
+    /**
+     * Contains 0, 1, or two Ships being unloaded
+     */
+    protected SortedSet<Ship> berth;
+
+    /**
+     * Time in the system for each Ship
+     */
+    protected double timeInSystem;
+
+    /**
+     * Delay in the queue for each Ship
+     */
+    protected double delayInQueue;
+
+    /**
+     * Instantiate queue and berth containers
+     */
+    public TwoCraneBerthsOpenDis7() {
+        this.queue = new TreeSet<>();
+        this.berth = new TreeSet<>();
+    }
+
+    /**
+     * Clear queue and berth containers
+     */
+    @Override
+    public void reset() {
+        super.reset();
+        queue.clear();
+        berth.clear();
+        timeInSystem = Double.NaN;
+        delayInQueue = Double.NaN;
+    }
+
+    /**
+     * Only PropertyChangeEvents
+     */
+    public void doRun() {
+        firePropertyChange("queue", getQueue());
+        firePropertyChange("berth", getBerth());
+        firePropertyChange("timeInSystem", getTimeInSystem());
+        firePropertyChange("delayInQueue", getDelayInQueue());
+    }
+
+    /**
+     * Add the given Ship to queue<br>
+     * If berths is empty, schedule StartUnloadingTwoCranes<br>
+     * If berths has 1 Ship, schedule SwitchToOneCrane
+     *
+     * @param ship Given Ship arriving to harbor
+     */
+    public void doArrival(Ship ship) {
+
+        ship.stampTime();
+
+        SortedSet<Ship> oldQueue = getQueue();
+        queue.add(ship);
+        firePropertyChange("queue", oldQueue, getQueue());
+
+        if (berth.isEmpty()) {
+            waitDelay("StartUnloadingTwoCranes", 0.0, Priority.HIGH);
+        }
+
+        if (berth.size() == 1) {
+            waitDelay("SwitchToOneCrane", 0.0);
+        }
+    }
+
+    /**
+     * Remove the first Ship from queue<br>
+     * DelayInQueue is elapsedTime of that Ship<br>
+     * Add the ship to berth container<br>
+     * Schedule EndUnloadingTwoCranes at half the remaining time
+     */
+    public void doStartUnloadingTwoCranes() {
+        SortedSet<Ship> oldQueue = getQueue();
+        Ship ship = queue.first();
+        queue.remove(ship);
+        firePropertyChange("queue", oldQueue, getQueue());
+
+        delayInQueue = ship.getElapsedTime();
+        firePropertyChange("delayInQueue", getDelayInQueue());
+
+        ship.stampTime();
+
+        SortedSet<Ship> oldBerth = getBerth();
+        berth.add(ship);
+        firePropertyChange("berth", oldBerth, getBerth());
+
+        waitDelay("EndUnloadingTwoCranes", 0.5 * ship.getRemainingUnloadingTime());
+    }
+
+    /**
+     * Remove the (one) Ship from berth<br>
+     * TimeInSystem is the age of the Ship
+     */
+    public void doEndUnloadingTwoCranes() {
+        SortedSet<Ship> oldBerth = getBerth();
+        Ship ship = berth.first();
+        berth.remove(ship);
+        firePropertyChange("berth", oldBerth, getBerth());
+
+        timeInSystem = ship.getAge();
+        firePropertyChange("timeInSystem", getTimeInSystem());
+    }
+
+    /**
+     * This event is when a Ship arrives to find only one other Ship being
+     * unloaded.<br>
+     * Credit the ship in the berth with work at a rate of 2 (since 2 cranes
+     * have been unloading it<br>
+     * Interrupt EndUnloadingTwoCranes<br>
+     * Schedule EndUnloadingOneCrane with the Ship already in the berth<br>
+     * Schedule StartUnloadingOneCrane
+     */
+    public void doSwitchToOneCrane() {
+        Ship ship = berth.first();
+        ship.work(2.0);
+        ship.stampTime();
+
+        interrupt("EndUnloadingTwoCranes");
+
+        waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship);
+
+        waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH);
+    }
+
+    /**
+     * Pop the first Ship from the queue<br>
+     * delayInQueue is elapsedTime (from Arrival event)<br>
+     * Add that Ship to berth container<br>
+     * Schedule EndUnloadingOneCrane with that Ship
+     */
+    public void doStartUnloadingOneCrane() {
+        SortedSet<Ship> oldQueue = getQueue();
+        Ship ship = queue.first();
+        queue.remove(ship);
+        firePropertyChange("queue", oldQueue, getQueue());
+
+        delayInQueue = ship.getElapsedTime();
+        firePropertyChange("delayInQueue", getDelayInQueue());
+
+        ship.stampTime();
+
+        SortedSet<Ship> oldBerth = getBerth();
+        berth.add(ship);
+        firePropertyChange("berth", oldBerth, getBerth());
+
+        waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship);
+    }
+
+    /**
+     * Remove given Ship from berth<br>
+     * If Ships in queue, schedule StartUnloadingOneCrane<br>
+     * If queue is empty, schedule SwitchToTwoCranes<br>
+     * timeInSystem is age of Ship
+     * 
+     * @param ship Given Ship
+     */
+    public void doEndUnloadingOneCrane(Ship ship) {
+        SortedSet<Ship> oldBerth = getBerth();
+        berth.remove(ship);
+        firePropertyChange("berth", oldBerth, getBerth());
+
+        if (queue.size() > 0) {
+            waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH);
+        }
+
+        if (queue.isEmpty() && berth.size() == 1) {
+            waitDelay("SwitchToTwoCranes", 0.0);
+        }
+
+        timeInSystem = ship.getAge();
+        firePropertyChange("timeInSystem", getTimeInSystem());
+    }
+
+    /**
+     * Credit the work of the remaining Ship in berth at unit rate<br>
+     * Interrupt EndUnloadingOneCrane<br>
+     * Schedule EndUnloadingTwoCranes at double the rate (i.e., half the remaining time)
+     */
+    public void doSwitchToTwoCranes() {
+        Ship ship = berth.first();
+        ship.work(1.0);
+        ship.stampTime();
+
+        interrupt("EndUnloadingOneCrane", ship);
+
+        waitDelay("EndUnloadingTwoCranes",
+                0.5 * ship.getRemainingUnloadingTime());
+    }
+
+    /**
+     * 
+     * @return Shallow copy of queue
+     */
+    public SortedSet<Ship> getQueue() {
+        return new TreeSet<>(queue);
+    }
+
+    /**
+     * 
+     * @return Shallow copy of berth
+     */
+    public SortedSet<Ship> getBerth() {
+        return new TreeSet<>(berth);
+    }
+
+    /**
+     * 
+     * @return The timeInSystem
+     */
+    public double getTimeInSystem() {
+        return timeInSystem;
+    }
+
+    /**
+     * 
+     * @return The delayInQueue
+     */
+    public double getDelayInQueue() {
+        return delayInQueue;
+    }
+}
diff --git a/examples/src/SimkitOpenDis7Examples/run/RunTwoCranesBerthOpenDis7.java b/examples/src/SimkitOpenDis7Examples/run/RunTwoCranesBerthOpenDis7.java
new file mode 100644
index 0000000000..4c095942ba
--- /dev/null
+++ b/examples/src/SimkitOpenDis7Examples/run/RunTwoCranesBerthOpenDis7.java
@@ -0,0 +1,86 @@
+package SimkitOpenDis7Examples.run;
+
+import SimkitOpenDis7Examples.ShipArrivalProcess;
+import SimkitOpenDis7Examples.TwoCraneBerthsOpenDis7;
+import simkit.Schedule;
+import simkit.random.RandomVariate;
+import simkit.random.RandomVariateFactory;
+import simkit.stat.CollectionSizeTimeVaryingStats;
+import simkit.stat.SimpleStatsTally;
+
+/**
+ * Run simple two-berth model for 10 years (3650 days).
+ * <h2>Output:</h2><pre>
+ShipArrivalProcess.1
+	unloadTimeGenerator = Uniform (0.500, 1.500)
+	interarrivalTimeGenerator = Exponential (0.700)
+TwoCraneBerthsOpenDis7.2
+
+Simulation ended at time 3,650.0
+
+Number of ships arriving:	5,135
+Number of ships unloaded:	5,129
+Maximum # in queue:		11
+Average # in queue:		0.6834
+Average # busy berths:		1.1737
+Average time in system:		1.3207
+Average delay in queue:		0.4857
+</pre>
+* 
+ * @author ahbuss
+ */
+public class RunTwoCranesBerthOpenDis7 {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        RandomVariate interarrivalTimeGenerator =
+                RandomVariateFactory.getInstance("Exponential", 0.7);
+        RandomVariate unloadingTimeGenerator =
+                RandomVariateFactory.getInstance("Uniform", 0.5, 1.5);
+        ShipArrivalProcess shipArrivalProcess =
+                new ShipArrivalProcess(interarrivalTimeGenerator,
+                    unloadingTimeGenerator);
+        
+        TwoCraneBerthsOpenDis7 twoCraneBerths = new TwoCraneBerthsOpenDis7();
+        shipArrivalProcess.addSimEventListener(twoCraneBerths);
+        
+        SimpleStatsTally delayInQueueStat = new SimpleStatsTally("delayInQueue");
+        SimpleStatsTally timeInSystemStat = new SimpleStatsTally("timeInSystem");
+        CollectionSizeTimeVaryingStats numberInQueueStat = 
+                new CollectionSizeTimeVaryingStats("queue");
+        CollectionSizeTimeVaryingStats numberInBerthStat = 
+                new CollectionSizeTimeVaryingStats("berth");
+//        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper();
+//        twoCraneBerths.addPropertyChangeListener(simplePropertyDumper);
+        
+        twoCraneBerths.addPropertyChangeListener(delayInQueueStat);
+        twoCraneBerths.addPropertyChangeListener(timeInSystemStat);
+        twoCraneBerths.addPropertyChangeListener(numberInQueueStat);
+        twoCraneBerths.addPropertyChangeListener(numberInBerthStat);
+        
+        System.out.println(shipArrivalProcess);
+        System.out.println(twoCraneBerths);
+        
+        double stopTime = 10 * 365;
+        Schedule.stopAtTime(stopTime);
+        Schedule.setVerbose(false);
+        
+        Schedule.reset();
+        Schedule.startSimulation();
+        
+        System.out.printf("%nSimulation ended at time %,.1f%n%n",
+                Schedule.getSimTime());
+        
+        System.out.printf("Number of ships arriving:\t%,d%n", shipArrivalProcess.getNumberArrivals());
+        System.out.printf("Number of ships unloaded:\t%,d%n", timeInSystemStat.getCount());
+        System.out.printf("Maximum # in queue:\t\t%.0f%n", numberInQueueStat.getMaxObs());
+        System.out.printf("Average # in queue:\t\t%.4f%n", numberInQueueStat.getMean());
+        System.out.printf("Average # busy berths:\t\t%.4f%n", numberInBerthStat.getMean());
+        System.out.printf("Average time in system:\t\t%.4f%n",
+                timeInSystemStat.getMean());
+        System.out.printf("Average delay in queue:\t\t%.4f%n",
+                delayInQueueStat.getMean());    }
+
+}
diff --git a/examples/src/SimkitOpenDis7Examples/run/RunTwoCranesBerthOpenDis7Log.txt b/examples/src/SimkitOpenDis7Examples/run/RunTwoCranesBerthOpenDis7Log.txt
new file mode 100644
index 0000000000..1f19772e7f
--- /dev/null
+++ b/examples/src/SimkitOpenDis7Examples/run/RunTwoCranesBerthOpenDis7Log.txt
@@ -0,0 +1,23 @@
+ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=SimkitOpenDis7Examples/run/RunTwoCranesBerthOpenDis7.java -Drun.class=SimkitOpenDis7Examples.run.RunTwoCranesBerthOpenDis7 run-single
+init:
+Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties
+deps-jar:
+Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties
+Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes
+compile-single:
+run-single:
+ShipArrivalProcess.1
+	unloadTimeGenerator = Uniform (0.500, 1.500)
+	interarrivalTimeGenerator = Exponential (0.700)
+TwoCraneBerthsOpenDis7.2
+
+Simulation ended at time 3,650.0
+
+Number of ships arriving:	5,135
+Number of ships unloaded:	5,129
+Maximum # in queue:		11
+Average # in queue:		0.6834
+Average # busy berths:		1.1737
+Average time in system:		1.3207
+Average delay in queue:		0.4857
+BUILD SUCCESSFUL (total time: 4 seconds)
-- 
GitLab