如何模拟快餐店的顾客

时间:2013-11-05 23:38:19

标签: java algorithm

好。我实际上遇到了逻辑问题,而不是主方法的实际编码问题。 这是背景:

  

您的程序将允许管理员为其运行多个模拟   不同数量的客户确定最佳数量   服务器聘请。客户的确切服务时间很难   预测。使用基于过去观察的平均时间是一个   可能的方法。但是,更现实的策略是使用平均值   最短和最长服务时间并生成每个客户的服务   这两个数字之间的随机时间。该计划将允许   经理设定最短和最长服务时间。   预测客户到达的频率(通常由客户表示)   客户到达间隔时间)是另一个需要解决的问题。再次,   使用类似于生成服务时间的策略。该程序   将允许经理输入最小和最大到达间隔   倍。每个客户到达之间的确切时间   在两个到达间隔时间之间随机生成。

     

您的程序将读入以下数据:

     
      
  • 最短和最长服务时间(以分钟为单位)
  •   
  • 最短和最长到达间隔时间(以分钟为单位)
  •   
  • 客户数量
  •   
     

输入数据项后,程序将显示

     
      
  • 客户的平均等待时间
  •   
  • 在整个模拟期间排队等候的最大客户数(最大队列长度)。
  •   
     

在这种情况下,输入变量是随机的   自然,只运行一次模拟不适合绘图   可靠的推论。所以,程序也应该允许经理   多次运行模拟。

我写了程序的伪代码,看起来没问题,直到我手工工作,并意识到有些时间是实际的时间,有些是持续时间。

我遇到的问题是,我可以计算某些东西的唯一方法是使用先前客户的信息,因为该客户已从队列中删除(从单个链接列表中调整),该信息已不再可用。

如何按时间而不是客户到达来组织模拟? (算法帮助会优先考虑代码,因为它最能帮助我理解逻辑,这就是我遇到的问题。)

以下是我在main方法中的代码:

/**
 * Class FastFoodSimulation simulates customer service at a fast food restaurant.
 * This simulation serves as a tool for managers to determine how many servers are needed
 * for average amount of customers to be serviced in a timely manner.
 * 
 * @author (Ebony Brewer) 
 * @version (10272013)
 */
import javax.swing.JOptionPane;
import java.util.Random;

public class FastFoodSimulation
{
    public static void main(String args[])
    {
    int time;
    boolean reRun = true;
    int maxQueueLength;
    int customerCounter;
    int serviceTime;
    int arrivalTime;
    int departureTime;
    int waitTime;
    int interArrivalTime;
    int totalTime;
    int totalWaitTime;

    do
    {
        int minServiceTime = Integer.parseInt(JOptionPane.showInputDialog("Enter Minimum Service Time (in minutes)."));
        int maxServiceTime = Integer.parseInt(JOptionPane.showInputDialog("Enter Maximum Service Time (in minutes)."));
        int minInterArrivalTime = Integer.parseInt(JOptionPane.showInputDialog("Enter Minimum Time Between Customers(in minutes)."));
        int maxInterArrivalTime = Integer.parseInt(JOptionPane.showInputDialog("Enter Maximum Time Between Customers(in minutes)."));
        int numberOfCustomers = Integer.parseInt(JOptionPane.showInputDialog("Enter Number of Customers to Simulate."));

        time = 0;
        //LinkedQueue queue = new LinkedQueue();
        maxQueueLength = 0;
        customerCounter = 0;
        arrivalTime = 0;
        departureTime = 0;
        waitTime = 0;
        totalTime = 0;
        totalWaitTime = 0;

        while(customerCounter < numberOfCustomers)
        {
            serviceTime = randInt(minServiceTime, maxServiceTime);
            interArrivalTime = randInt(minInterArrivalTime, maxInterArrivalTime);
            arrivalTime = time + interArrivalTime;

            SimulationCustomer cust = new SimulationCustomer();
            cust.setServiceTime(serviceTime);
            cust.setInterArrivalTime(interArrivalTime);
            cust.setArrivalTime(arrivalTime);

            if(time == cust.getArrivalTime() && maxQueueLength == 0)
            {
                //queue.offer(cust);
                customerCounter++;
                departureTime = arrivalTime + serviceTime;
                totalTime = departureTime - arrivalTime;
                cust.setWaitTime(0);
                cust.setDepartureTime(departureTime);
                cust.setTotalTime(totalTime);
                //int length = queue.size();
                //if(length > maxQueueLength)
                  //  maxQueueLength = length;
                //queue.remove(cust);
                time++;
            }
            else if(time == cust.getArrivalTime() && maxQueueLength >= 1)
            {
                //queue.offer(cust);
                customerCounter++;
            }
        }
    }
    while(reRun);
}
/**
 * Returns a psuedo-random number between min and max, inclusive.
 * The difference between min and max can be at most
 * Integer.MAX_VALUE - 1
 * By Greg Case @ http://stackoverflow.com/questions/363681/generating-random-numbers-in-a-range-with-java
 *
 * @param min Minimim value
 * @param max Maximim value.  Must be greater than min.
 * @return Integer between min and max, inclusive.
 * @see java.util.Random#nextInt(int)
 */
public static int randInt(int min, int max)
{

    // Usually this can be a field rather than a method variable
    Random rand = new Random();

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
}

}

2 个答案:

答案 0 :(得分:1)

您没有完整/可行的模拟逻辑结构。

目前,您在走进门的顾客驾驶模拟。刚刚设置了他们的到达时间,然后检查到达时间(冗余)..然后再尝试决定如何处理它们。

走在门口的顾客推动循环并不一定是错的 - 但它也不一定是最简单或最简单的。你必须通过某种东西来驱动循环,但可以随时间推动。

您需要在餐厅内管理“州”。目前,您没有逻辑将客户放入队列,完成客户服务或为队列中的下一个客户提供服务。

餐厅内的“客户状态”定义了过渡,即事件,您的程序必须实现这些事件。该模拟的模型是正确的。

关于你的意见:所有生成的&amp;指定的时间是 interval 。您可能在内部想要使用或生成参考时间时间戳来安排即将发生的事件,或者打印以进行日志记录。

使用后需要上一位客户的信息没有问题 - 您可以保留last变量&amp;稍后使用,或在您仍有客户时随机生成nextCustomerTime。这一切都很简单。

最后,将“单一模拟运行”代码放入一个方法中,或者(或许甚至更好)一个单独的类。更简单更清晰将使能够更清楚地隔离您的相关逻辑,对其进行操作&amp;专注于做正确的事。

答案 1 :(得分:1)

您应该使用PriorityQueue<FastFoodEvent>个实例,其中的事件包括CustomerEntersCustomerOrdersCustomerServed。事件都有一个time变量,队列将按时间排序。

您需要一个Customer类,其中包含id和一些I / O方法。

您需要一些Cashier个对象,每个对象都会尝试从队列中处理客户。当收银员处理客户时,他不会处理另一个客户。或者,他可能有自己的队列。