SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
CallEv.java
1package tutorial;
2
3import umontreal.ssj.simevents.*;
4import umontreal.ssj.rng.*;
5import umontreal.ssj.randvar.*;
6import umontreal.ssj.probdist.*;
7import umontreal.ssj.stat.Tally;
8import java.io.*;
9import java.util.*;
10
11public class CallEv {
12
13 static final double HOUR = 3600.0; // Time is in seconds.
14
15 // Data
16 // Arrival rates are per hour, service and patience times are in seconds.
17 int numDays; // Number of days to simulate.
18 double openingTime; // Opening time of the center (in hours).
19 int numPeriods; // Number of working periods (hours) in the day.
20 int[] numAgents; // Number of agents for each period.
21 double[] lambda; // Base arrival rate lambda_j for each j.
22 double alpha0; // Parameter of gamma distribution for W.
23 double p; // Probability that patience time is 0.
24 double nu; // Parameter of exponential for patience time.
25 double alpha, beta; // Parameters of gamma service time distribution.
26 double s; // Want stats on waiting times smaller than s.
27
28 // Variables
29 double busyness; // Current value of W.
30 double arrRate = 0.0; // Current arrival rate.
31 int nAgents; // Number of agents in current period.
32 int nBusy; // Number of agents occupied;
33 int nArrivals; // Number of arrivals today;
34 int nAbandon; // Number of abandonments during the day.
35 int nGoodQoS; // Number of waiting times less than s today.
36 double nCallsExpected; // Expected number of calls per day.
37
38 Event nextArrival = new Arrival(); // The next Arrival event.
39
40 RandomStream streamW = new MRG32k3a(); // For W.
41 RandomStream streamArr = new MRG32k3a(); // For arrivals.
42 RandomStream streamPatience = new MRG32k3a(); // For patience times.
43 GammaGen genServ; // For service times; created in readData().
44
45 LinkedListStat<Call> waitList = new LinkedListStat<Call>("Waiting calls");
46
47 Tally statArrivals = new Tally("Number of arrivals per day");
48 Tally statWaits = new Tally("Average waiting time per customer");
49 Tally statWaitsDay = new Tally("Waiting times within a day");
50 Tally statGoodQoS = new Tally("Proportion of waiting times < s");
51 Tally statAbandon = new Tally("Proportion of calls lost");
52
53 class Call {
54 double arrivTime, servTime, patienceTime;
55 }
56
57 static public void main(String[] args) throws IOException {
58 new CallEv(args.length == 1 ? args[0] : "CallEv.dat");
59 }
60
61 public CallEv(String fileName) throws IOException {
62 readData(fileName);
63 for (int i = 1; i <= numDays; i++)
64 simulOneDay();
65 System.out.println("\n Num. calls expected = " + nCallsExpected + "\n");
66 statArrivals.setConfidenceIntervalStudent();
68 statGoodQoS.setConfidenceIntervalStudent();
69 statAbandon.setConfidenceIntervalStudent();
70 System.out.println(statArrivals.report(0.9, 3));
71 System.out.println(statWaits.report(0.9, 3));
72 System.out.println(statGoodQoS.report(0.9, 3));
73 System.out.println(statAbandon.report(0.9, 3));
74 }
75
76 class NextPeriod extends Event {
77 int j; // Number of the new period.
78
79 public NextPeriod(int period) {
80 j = period;
81 }
82
83 public void actions() {
84 if (j < numPeriods) {
85 nAgents = numAgents[j];
86 arrRate = busyness * lambda[j] / HOUR;
87 if (j == 0)
88 nextArrival.schedule(ExponentialDist.inverseF(arrRate, streamArr.nextDouble()));
89 else {
90 checkQueue();
91 nextArrival.reschedule((nextArrival.time() - Sim.time()) * lambda[j - 1] / lambda[j]);
92 }
93 new NextPeriod(j + 1).schedule(1.0 * HOUR);
94 } else
95 nextArrival.cancel(); // End of the day.
96 }
97 }
98
99 class Arrival extends Event {
100 public void actions() {
101 nextArrival.schedule(ExponentialDist.inverseF(arrRate, streamArr.nextDouble()));
102 nArrivals++;
103 Call call = new Call(); // Call just arrived.
104 call.servTime = genServ.nextDouble(); // Generate service time.
105 if (nBusy < nAgents) { // Start service immediately.
106 nBusy++;
107 nGoodQoS++;
108 statWaitsDay.add(0.0);
109 new CallCompletion().schedule(call.servTime);
110 } else { // Join the queue.
111 call.patienceTime = generPatience();
112 call.arrivTime = Sim.time();
113 waitList.addLast(call);
114 }
115 }
116 }
117
118 class CallCompletion extends Event {
119 public void actions() {
120 nBusy--;
121 checkQueue();
122 }
123 }
124
125 public void checkQueue() {
126 // Start answering new calls if agents are free and queue not empty.
127 while ((waitList.size() > 0) && (nBusy < nAgents)) {
128 Call call = waitList.removeFirst();
129 double wait = Sim.time() - call.arrivTime;
130 if (call.patienceTime < wait) { // Caller has abandoned.
131 nAbandon++;
132 wait = call.patienceTime; // Effective waiting time.
133 } else {
134 nBusy++;
135 new CallCompletion().schedule(call.servTime);
136 }
137 if (wait < s)
138 nGoodQoS++;
139 statWaitsDay.add(wait);
140 }
141 }
142
143 public double generPatience() {
144 // Generates the patience time for a call.
145 double u = streamPatience.nextDouble();
146 if (u <= p)
147 return 0.0;
148 else
149 return ExponentialDist.inverseF(nu, (1.0 - u) / (1.0 - p));
150 }
151
152 public void readData(String fileName) throws IOException {
153 // Reads data and construct arrays.
154 Locale loc = Locale.getDefault();
155 Locale.setDefault(Locale.US); // to read reals as 8.3 instead of 8,3
156 BufferedReader input = new BufferedReader(new FileReader(fileName));
157 Scanner scan = new Scanner(input);
158 numDays = scan.nextInt();
159 scan.nextLine();
160 openingTime = scan.nextDouble();
161 scan.nextLine();
162 numPeriods = scan.nextInt();
163 scan.nextLine();
164 numAgents = new int[numPeriods];
165 lambda = new double[numPeriods];
166 nCallsExpected = 0.0;
167 for (int j = 0; j < numPeriods; j++) {
168 numAgents[j] = scan.nextInt();
169 lambda[j] = scan.nextDouble();
170 nCallsExpected += lambda[j];
171 scan.nextLine();
172 }
173 alpha0 = scan.nextDouble();
174 scan.nextLine();
175 p = scan.nextDouble();
176 scan.nextLine();
177 nu = scan.nextDouble();
178 scan.nextLine();
179 alpha = scan.nextDouble();
180 scan.nextLine();
181 beta = scan.nextDouble();
182 scan.nextLine();
183 s = scan.nextDouble();
184 scan.close();
185 Locale.setDefault(loc);
186
187 // genServ can be created only after its parameters are known.
188 genServ = new GammaAcceptanceRejectionGen( // Faster than inversion
189 new MRG32k3a(), alpha, beta);
190 }
191
192 public void simulOneDay() {
193 Sim.init();
194 statWaitsDay.init();
195 nArrivals = 0;
196 nAbandon = 0;
197 nGoodQoS = 0;
198 nBusy = 0;
199 busyness = GammaDist.inverseF(alpha0, alpha0, 8, streamW.nextDouble());
200 new NextPeriod(0).schedule(openingTime * HOUR);
201 Sim.start();
202 // Here the simulation is running...
203 statArrivals.add((double) nArrivals);
204 statAbandon.add((double) nAbandon / nCallsExpected);
205 statGoodQoS.add((double) nGoodQoS / nCallsExpected);
206 statWaits.add(statWaitsDay.sum() / nCallsExpected);
207 }
208}
void actions()
This is the method that is executed when this event occurs.
Definition CallEv.java:100
void actions()
This is the method that is executed when this event occurs.
Definition CallEv.java:119
void actions()
This is the method that is executed when this event occurs.
Definition CallEv.java:83
Extends the class ContinuousDistribution for the exponential distribution tjoh95a  (page 494) with me...
double inverseF(double u)
Returns the inverse distribution function .
This class implements random variate generators for the gamma distribution.
Definition GammaGen.java:47
Extends the abstract class RandomStreamBase by using as a backbone (or main) generator the combined m...
Definition MRG32k3a.java:46
This abstract class provides event scheduling tools.
Definition Event.java:53
Event()
Constructs a new event instance, which can be placed afterwards into the event list of the default si...
Definition Event.java:126
void schedule(double delay)
Schedules this event to happen in delay time units, i.e., at time sim.time() + delay,...
Definition Event.java:153
This class extends ListWithStat, and uses a linked list as the internal data structure.
This static class contains the executive of a discrete-event simulation.
Definition Sim.java:48
static double time()
Returns the current value of the simulation clock.
Definition Sim.java:59
A subclass of StatProbe.
Definition Tally.java:47
void setConfidenceIntervalStudent()
Indicates that a confidence interval on the true mean, based on the normality assumption,...
Definition Tally.java:582
String report()
Returns a formatted string that contains a report on this probe.
Definition Tally.java:397
This interface defines the basic structures to handle multiple streams of uniform (pseudo)random numb...