基本上,问题是为在银行排队等候的人创建模拟。需要一些标准,例如平均等待时间,平均分钟数,平均最长等待时间......等等。它还要求每1000次运行我的程序3次(使用for循环)。问题是,每次运行代码时,答案都会因某种原因而加起来,我似乎无法知道原因。例如,在上一次运行中,模拟运行的次数应为1000次,而是将所有先前的运行一起添加并给出3000次。
此外,while循环之外的所有变量(averageWaitingTime,averageSimulationTime ...等)都给出了错误的答案。这是因为,例如,对于平均等待时间,它会不断添加相同的等待时间值。我无法弄清楚为什么。
public class QueueSimulation {
public static void main(String[] args) {
Queue<Customer> q = new LinkedList<Customer>();
int numServed = 0;
int averageNumServed = 0;
int waitingTime = 0;
int maxWaitingTime = 0;
int averageLongestWaitingTime = 0;
int totalWaitingTime = 0;
double averageWaitingTime = 0;
int maxQueueSize = 0;
int timeDone = 0;
int totalSimulationTime = 0;
int averageSimulationTime = 0;
int numSimulationRan = 0;
Random randomGenerator = new Random();
int time = 0;
int processingTime = 0;
int totalProcessingTime = 0;
for (int i = 0; i < 1000; i++) {
double arrivalRate = 0.2;
int maxProcessingTime = 5;
while (time < 8 * 60) {
if (Math.random() < 0.2) {
System.out.println("A new customer arrives at time " + time);
processingTime = randomGenerator.nextInt(maxProcessingTime);
totalProcessingTime += processingTime;
Customer c = new Customer(time, processingTime);
q.add(c);
if (q.size() > maxQueueSize)
maxQueueSize = q.size();
}
if (waitingTime > maxWaitingTime)
maxWaitingTime = waitingTime;
averageLongestWaitingTime += maxWaitingTime;
// serve the next customer
if (time > timeDone) // service is available
if (!q.isEmpty()) {
Customer c = q.remove();
timeDone = time + c.getProcessingTime();
// calculate the waiting time of this customer
waitingTime = time - c.getArrivalTime();
// update total waiting time of all customers
totalWaitingTime += waitingTime;
// service this customer
numServed++;
}
time++;
if (time > 8 * 60)
while (!q.isEmpty()) {
Customer c = q.remove();
timeDone = time + c.getProcessingTime();
// calculate the waiting time of this customer
waitingTime = time - c.getArrivalTime();
// update total waiting time of all customers
totalWaitingTime += waitingTime;
// service this customer
numServed++;
}
}
averageWaitingTime += (totalWaitingTime / numServed);
totalSimulationTime = timeDone;
averageSimulationTime += totalSimulationTime;
averageNumServed += numServed;
numSimulationRan += 1;
}
System.out.println();
System.out.println("Average waiting time per customer: " + (double) averageWaitingTime / 1000);
System.out.println("Average longest waiting time: " + (double) averageLongestWaitingTime / 1000);
System.out.println("Average number of minutes: " + (double) averageSimulationTime / 1000);
System.out.println("Longest waiting time: " + maxWaitingTime);
System.out.println("Average number of customers " + (double) averageNumServed / 1000);
System.out.println("Number of times the simulation ran: " + numSimulationRan);
for (int j = 0; j < 1000; j++) {
double arrivalRate = 0.5;
int maxProcessingTime = 3;
while (time < 8 * 60) {
if (Math.random() < 0.5) {
System.out.println("A new customer arrives at time " + time);
processingTime = randomGenerator.nextInt(maxProcessingTime);
totalProcessingTime += processingTime;
Customer c = new Customer(time, processingTime);
q.add(c);
if (q.size() > maxQueueSize)
maxQueueSize = q.size();
}
if (waitingTime > maxWaitingTime)
maxWaitingTime = waitingTime;
averageLongestWaitingTime += maxWaitingTime;
// serve the next customer
if (time > timeDone) // service is available
if (!q.isEmpty()) {
Customer c = q.remove();
timeDone = time + c.getProcessingTime();
// calculate the waiting time of this customer
waitingTime = time - c.getArrivalTime();
// update total waiting time of all customers
totalWaitingTime += waitingTime;
// service this customer
numServed++;
}
time++;
if (time > 8 * 60)
while (!q.isEmpty()) {
Customer c = q.remove();
timeDone = time + c.getProcessingTime();
// calculate the waiting time of this customer
waitingTime = time - c.getArrivalTime();
// update total waiting time of all customers
totalWaitingTime += waitingTime;
// service this customer
numServed++;
}
}
averageWaitingTime += (totalWaitingTime / numServed);
totalSimulationTime = timeDone;
averageSimulationTime += totalSimulationTime;
averageNumServed += numServed;
numSimulationRan += 1;
}
System.out.println();
System.out.println("Average waiting time per customer: " + (double) averageWaitingTime / 1000);
System.out.println("Average longest waiting time: " + (double) averageLongestWaitingTime / 1000);
System.out.println("Average number of minutes: " + (double) averageSimulationTime / 1000);
System.out.println("Longest waiting time: " + maxWaitingTime);
System.out.println("Average number of customers " + (double) averageNumServed / 1000);
System.out.println("Number of times the simulation ran: " + numSimulationRan);
for (int k = 0; k < 1000; k++) {
double arrivalRate = 0.68;
int maxProcessingTime = 4;
while (time < 8 * 60) {
if (Math.random() < 0.68) {
System.out.println("A new customer arrives at time " + time);
processingTime = randomGenerator.nextInt(maxProcessingTime);
totalProcessingTime += processingTime;
Customer c = new Customer(time, processingTime);
q.add(c);
if (q.size() > maxQueueSize)
maxQueueSize = q.size();
}
if (waitingTime > maxWaitingTime)
maxWaitingTime = waitingTime;
averageLongestWaitingTime += maxWaitingTime;
// serve the next customer
if (time > timeDone) // service is available
if (!q.isEmpty()) {
Customer c = q.remove();
timeDone = time + c.getProcessingTime();
// calculate the waiting time of this customer
waitingTime = time - c.getArrivalTime();
// update total waiting time of all customers
totalWaitingTime += waitingTime;
// service this customer
numServed++;
}
time++;
if (time > 8 * 60)
while (!q.isEmpty()) {
Customer c = q.remove();
timeDone = time + c.getProcessingTime();
// calculate the waiting time of this customer
waitingTime = time - c.getArrivalTime();
// update total waiting time of all customers
totalWaitingTime += waitingTime;
// service this customer
numServed++;
}
}
averageWaitingTime += (totalWaitingTime / numServed);
totalSimulationTime = timeDone;
averageSimulationTime += totalSimulationTime;
averageNumServed += numServed;
numSimulationRan += 1;
}
System.out.println();
System.out.println("Average waiting time per customer: " + (double) averageWaitingTime / 1000);
System.out.println("Average longest waiting time: " + (double) averageLongestWaitingTime / 1000);
System.out.println("Average number of minutes: " + (double) averageSimulationTime / 1000);
System.out.println("Longest waiting time: " + maxWaitingTime);
System.out.println("Average number of customers " + (double) averageNumServed / 1000);
System.out.println("Number of times the simulation ran: " + numSimulationRan);
}
}
输出:
A new customer arrives at time 5
A new customer arrives at time 10
A new customer arrives at time 11
A new customer arrives at time 12
A new customer arrives at time 25
A new customer arrives at time 28
A new customer arrives at time 31
A new customer arrives at time 45
A new customer arrives at time 48
A new customer arrives at time 51
A new customer arrives at time 59
A new customer arrives at time 64
A new customer arrives at time 68
A new customer arrives at time 86
A new customer arrives at time 100
A new customer arrives at time 106
A new customer arrives at time 108
A new customer arrives at time 113
A new customer arrives at time 115
A new customer arrives at time 120
A new customer arrives at time 124
A new customer arrives at time 125
A new customer arrives at time 126
A new customer arrives at time 132
A new customer arrives at time 137
A new customer arrives at time 153
A new customer arrives at time 156
A new customer arrives at time 164
A new customer arrives at time 201
A new customer arrives at time 206
A new customer arrives at time 208
A new customer arrives at time 219
A new customer arrives at time 226
A new customer arrives at time 233
A new customer arrives at time 234
A new customer arrives at time 237
A new customer arrives at time 242
A new customer arrives at time 246
A new customer arrives at time 247
A new customer arrives at time 251
A new customer arrives at time 262
A new customer arrives at time 271
A new customer arrives at time 276
A new customer arrives at time 277
A new customer arrives at time 282
A new customer arrives at time 285
A new customer arrives at time 287
A new customer arrives at time 292
A new customer arrives at time 296
A new customer arrives at time 298
A new customer arrives at time 318
A new customer arrives at time 319
A new customer arrives at time 327
A new customer arrives at time 336
A new customer arrives at time 337
A new customer arrives at time 338
A new customer arrives at time 346
A new customer arrives at time 355
A new customer arrives at time 356
A new customer arrives at time 358
A new customer arrives at time 362
A new customer arrives at time 363
A new customer arrives at time 366
A new customer arrives at time 374
A new customer arrives at time 379
A new customer arrives at time 380
A new customer arrives at time 384
A new customer arrives at time 389
A new customer arrives at time 400
A new customer arrives at time 407
A new customer arrives at time 416
A new customer arrives at time 418
A new customer arrives at time 424
A new customer arrives at time 427
A new customer arrives at time 433
A new customer arrives at time 436
A new customer arrives at time 437
A new customer arrives at time 438
A new customer arrives at time 446
A new customer arrives at time 454
A new customer arrives at time 466
A new customer arrives at time 469
A new customer arrives at time 471
Average waiting time per customer: 1.0
Average longest waiting time: 2.714
Average number of minutes: 475.0
Longest waiting time: 8
Average number of customers 83.0
Number of times the simulation ran: 1000
Average waiting time per customer: 2.0
Average longest waiting time: 2.714
Average number of minutes: 950.0
Longest waiting time: 8
Average number of customers 166.0
Number of times the simulation ran: 2000
Average waiting time per customer: 3.0
Average longest waiting time: 2.714
Average number of minutes: 1425.0
Longest waiting time: 8
Average number of customers 249.0
Number of times the simulation ran: 3000
答案 0 :(得分:1)
有一个名为Don't Repeat Yourself or DRY的原则。在这个词被创造出来之前,我们常常开玩笑说,懒惰是程序员的一个好品质:如果你必须做两次,那么你经常这样做。
也许您可以考虑声明一些methods,因为您的程序似乎有三次相同的代码。
具有讽刺意味的是,有一件事你只做一次:初始化统计变量:
int numServed = 0;
...
如果您复制此部分并删除类型(因此它显示为numServed = 0;
等),然后再次复制它,它将重置这些变量。
但是,复制粘贴代码是不好的做法:现在你需要维护3倍的代码。
要解决此问题,您可以按照以下方式构建程序:
class QueueSimulation
{
public static void main(String[] args) {
for ( int test = 0; test < 3; test ++ ) {
int numServed = 0;
..
for ( int i = 0; i < 1000; i++) {
...
}
System.out.println();
....
}
}
}
没有重复的代码,它会对变量进行本地化,以便为每次模拟重置这些变量,从而解决您的问题。
这只是朝着正确方向迈出的一步。还有一个步骤是factor out处的abstraction levels方法,例如Top-Down and Bottom-Up design。
TLDR:一个好的经验法则是让任何方法适合{文本
在您的情况下:您正在运行相同的模拟3次。模拟的细节与运行模拟3次的方法无关。
这是另一个可能的大纲,我们将变量转换为QueueSimulation
类的字段。要初始化它们,我们只需实例化一个新的QueueSimulation。这是:
class QueueSimulation
{
public static void main(String[] args) {
for ( int test = 0; test < 3; test ++ ) {
QueueSimulation sim = new QueueSimulation();
sim.simulate();
sim.report();
}
}
Queue<Customer> q = new LinkedList<Customer>();
int numServed = 0;
...
int totalProcessingTime = 0;
public void simulate() {
for ( int i = 0; i < 1000 ) {
....
}
}
public void report() {
System.out.println( ....
...
}
}