1 package nl.tudelft.simulation.dsol.demo.des.mm1.step09;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.djutils.event.Event;
7 import org.djutils.event.EventListener;
8
9 import nl.tudelft.simulation.dsol.SimRuntimeException;
10 import nl.tudelft.simulation.dsol.experiment.Replication;
11 import nl.tudelft.simulation.dsol.model.AbstractDsolModel;
12 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterDouble;
13 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterException;
14 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterInteger;
15 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterMap;
16 import nl.tudelft.simulation.dsol.simulators.DevsSimulatorInterface;
17 import nl.tudelft.simulation.dsol.statistics.SimPersistent;
18 import nl.tudelft.simulation.dsol.statistics.SimTally;
19 import nl.tudelft.simulation.jstats.distributions.DistContinuous;
20 import nl.tudelft.simulation.jstats.distributions.DistExponential;
21
22
23
24
25
26
27
28
29
30
31
32
33 class DesQueueingModel9 extends AbstractDsolModel<Double, DevsSimulatorInterface<Double>> implements EventListener
34 {
35
36 private List<QueueEntry<Entity>> queue = new ArrayList<>();;
37
38
39 private int entityCounter = 0;
40
41
42 private int capacity = 1;
43
44
45 private int batchSize = 1;
46
47
48 private int busy = 0;
49
50
51 private DistContinuous interArrivalTime;
52
53
54 private DistContinuous processingTime;
55
56
57 private SimTally<Double> tallyTimeInQueue;
58
59
60 private SimTally<Double> tallyTimeInSystem;
61
62
63 private SimPersistent<Double> persistentUtilization;
64
65
66 private SimPersistent<Double> persistentQueueLength;
67
68
69
70
71
72 public DesQueueingModel9(final DevsSimulatorInterface<Double> simulator)
73 {
74 super(simulator);
75 try
76 {
77 InputParameterMap generatorMap = new InputParameterMap("generator", "Generator", "Generator", 1.0);
78 generatorMap
79 .add(new InputParameterDouble("intervalTime", "Average interval time", "Average interval time", 1.0, 1.0));
80 generatorMap.add(new InputParameterDouble("startTime", "Generator start time", "Generator start time", 0.0, 2.0));
81 generatorMap.add(new InputParameterInteger("batchSize", "Batch size", "batch size", 1, 3.0));
82 this.inputParameterMap.add(generatorMap);
83 InputParameterMap resourceMap = new InputParameterMap("resource", "Resource", "Resource", 2.0);
84 resourceMap.add(new InputParameterInteger("capacity", "Resource capacity", "Resource capacity", 1, 1.0));
85 resourceMap.add(new InputParameterDouble("serviceTime", "Average service time", "Average service time", 0.9, 2.0));
86 this.inputParameterMap.add(resourceMap);
87 this.simulator.addListener(this, Replication.END_REPLICATION_EVENT);
88 }
89 catch (InputParameterException e)
90 {
91 throw new SimRuntimeException("Error defining parameters for the model", e);
92 }
93 }
94
95 @Override
96 public void constructModel() throws SimRuntimeException
97 {
98 double startTime = 0.0;
99 try
100 {
101 this.capacity = (Integer) getInputParameter("resource.capacity");
102 this.batchSize = (Integer) getInputParameter("generator.batchSize");
103 startTime = (Double) getInputParameter("generator.startTime");
104 double iat = (Double) getInputParameter("generator.intervalTime");
105 this.interArrivalTime = new DistExponential(getDefaultStream(), iat);
106 double st = (Double) getInputParameter("resource.serviceTime");
107 this.processingTime = new DistExponential(getDefaultStream(), st);
108 }
109 catch (InputParameterException e)
110 {
111 throw new SimRuntimeException("Error retrieving parameters for the model", e);
112 }
113
114 this.tallyTimeInQueue = new SimTally<>("tQ", "Time in queue", this);
115 this.tallyTimeInSystem = new SimTally<>("tS", "Time in system", this);
116 this.persistentQueueLength = new SimPersistent<>("lQ", "Queue length", this);
117 this.persistentUtilization = new SimPersistent<>("Ut", "Server utilization", this);
118 this.persistentQueueLength.register(0.0, 0.0);
119 this.persistentUtilization.register(0.0, 0.0);
120
121 this.simulator.scheduleEventRel(startTime, () -> generate());
122 }
123
124
125
126
127 protected void generate()
128 {
129 double time = getSimulator().getSimulatorTime();
130 for (int i = 0; i < this.batchSize; i++)
131 {
132 Entity entity = new Entity(this.entityCounter++, time);
133 if (this.capacity - this.busy >= 1)
134 {
135
136 this.tallyTimeInQueue.register(0.0);
137 startProcess(entity);
138 }
139 else
140 {
141
142 this.queue.add(new QueueEntry<Entity>(entity, time));
143 this.persistentQueueLength.register(time, this.queue.size());
144 }
145 }
146 this.simulator.scheduleEventRel(this.interArrivalTime.draw(), () -> generate());
147 }
148
149
150
151
152
153 protected void startProcess(final Entity entity)
154 {
155 double time = getSimulator().getSimulatorTime();
156 this.busy++;
157 this.persistentUtilization.register(time, this.busy);
158 this.simulator.scheduleEventRel(this.processingTime.draw(), () -> endProcess(entity));
159 }
160
161
162
163
164
165 protected void endProcess(final Entity entity)
166 {
167 double time = getSimulator().getSimulatorTime();
168 this.busy--;
169 this.persistentUtilization.register(time, this.busy);
170 if (!this.queue.isEmpty())
171 {
172 QueueEntry<Entity> nextQueueEntry = this.queue.remove(0);
173 this.persistentQueueLength.register(time, this.queue.size());
174 this.tallyTimeInQueue.register(time - nextQueueEntry.getQueueInTime());
175 startProcess(nextQueueEntry.getEntity());
176 }
177 this.tallyTimeInSystem.register(time - entity.getCreateTime());
178 }
179
180
181
182
183 protected void reportStats()
184 {
185 this.persistentUtilization.endObservations(getSimulator().getReplication().getRunLength());
186 this.persistentQueueLength.endObservations(getSimulator().getReplication().getRunLength());
187
188 System.out.println(SimTally.reportHeader());
189 System.out.println(this.tallyTimeInQueue.reportLine());
190 System.out.println(this.tallyTimeInSystem.reportLine());
191 System.out.println(SimTally.reportFooter());
192
193 System.out.println(SimPersistent.reportHeader());
194 System.out.println(this.persistentQueueLength.reportLine());
195 System.out.println(this.persistentUtilization.reportLine());
196 System.out.println(SimPersistent.reportFooter());
197 }
198
199 @Override
200 public void notify(final Event event)
201 {
202 if (event.getType().equals(Replication.END_REPLICATION_EVENT))
203 {
204 reportStats();
205 }
206 }
207
208 }