java - 为什么每次我运行程序时它都会添加到最后一个

标签 java queue simulator

基本上,问题是为在银行排队等候的人们创建一个模拟。需要一些特定的标准,例如平均等待时间、平均分钟数、平均最长等待时间...等。它还要求运行我的程序 3 次,每次 1000 次(使用 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

最佳答案

有一个原则叫做 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( ....
         ...           
     }
 }

关于java - 为什么每次我运行程序时它都会添加到最后一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36460621/

相关文章:

java - Spring AMQP : CorrelationId changes between moment of sending and receiving a message

C# - 始终运行和出队的队列管理

css - 响应式设计在 iPhone 5s 中不起作用

ios - 模拟器的自定义 Expo 开发客户端

ios - Xamarin Auth IOS 模拟器将帐户保存到 KeyChain

java - 使用网络摄像头进行光线/颜色跟踪

java - InputStream.read() 返回的 int 值代表什么?

java - SNMP4J - 无法使其运行 SHA/AES 256 的 SNMP V3

java - 如何将数组的数据直接放入PriorityQueue

go - 如何关闭 channel