0

好的。实际上,我遇到的逻辑问题比主要方法的实际编码问题更多。这是背景:

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

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

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

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

  • 客户的平均等待时间
  • 在整个模拟过程中排队等候的顾客数量最多(最大排队长度)。

在这种情况下,输入变量本质上是随机的,仅运行一次模拟不足以得出可靠的推论。因此,该程序还应允许经理多次运行模拟。

我为该程序编写了伪代码,它看起来还不错,直到我手动操作它并意识到有些时间是实际时间,有些是持续时间。

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

如何按时间而不是客户到达来组织模拟?(算法帮助比编码更可取,因为它最能帮助我理解逻辑,这是我遇到的问题。)

这是我到目前为止在 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;
}

}

4

2 回答 2

1

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

目前,您通过走进门的客户来驱动模拟。刚刚设置了他们的到达时间,然后您检查到达时间(冗余).. 在尝试决定如何处理他们之前。

由走进门的顾客驾驶循环不一定是错误的——但也不一定是最简单或最容易的。你必须通过某些东西来驱动循环,但可以通过时间来驱动。

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

餐厅内的“客户状态”定义了转换,也就是事件,您的程序必须实现和建模才能使该模拟正确。

至于您的评论:所有生成和指定的时间都是间隔。您可能希望在内部使用或生成参考时间时间戳来安排即将发生的事件,或打印以用于记录目的。

在使用它后需要最后一个客户的信息没有问题——您可以保留一个last变量并在以后使用它,或者nextCustomerTime在您仍然拥有客户时随机生成。这一切都很简单。

最后,将您的“单次模拟运行”代码放入一个方法中,或者(也许更好)一个单独的类。更简单、更清晰将使能够更清楚地隔离您的相关逻辑,处理它并专注于使其正确。

于 2013-11-05T23:48:40.173 回答
1

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

您将需要一个Customer具有一个id和一些 I/O 方法的类。

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

于 2013-11-06T01:03:45.157 回答