【问题标题】:Modelling the queues at a restaurant at a college模拟大学餐厅的队列
【发布时间】:2020-02-09 08:33:22
【问题描述】:

以下是限制条件: 餐厅每天早上 6 点至晚上 11:59 营业(因此在 360 分钟营业)。

平均每 5 分钟就有一位顾客到达餐厅。 (因此一分钟内有 20% 的机会获得客户。)

餐厅需要 2 到 7 分钟来完成顾客的订单,而且由于整个餐厅只有一个人在经营,因此只有在将食物送达给前一位顾客后,才会为下一位排队的顾客提供服务。

虽然餐厅试图按照每个人进来的顺序为他们提供服务,但某些人群会被优先考虑。前辈将在晚辈之前送达;大二之前的大三;大二之前的大一。

到目前为止,我已经使用 Java Priority Queues 和 Maps 实现了以下代码。我试图通过他们进来的时间(从 360 及以上)和他们的等级来识别每个客户。然而,这是我第一次使用优先级队列和映射,我不太确定我是否做对了——事实上,它在下面返回了这个错误,尽管已经咨询过 API,但我不确定如何修复和其他一些 java 资源:

线程“main”java.lang.ClassCastException 中的异常:java.base/java.util.AbstractMap$SimpleEntry 无法转换为 java.base/java.lang.Comparable

import java.util.*;
import java.util.PriorityQueue;
import java.util.Comparator; 
import java.util.Map; 

class CustomerComparator implements Comparator<Customer>
{
   public int compare(Customer c1, Customer c2)
   {
      if(c1.grade < c2.grade)
         return 1; 
      else if(c1.grade > c2.grade)
         return -1;
      else
         return 0;  
   }
}

class Customer
{
   public int grade;
   public double waitingTime;
   
   public Customer(int grade, double waitingTime)
   {
      this.grade = grade;
      this.waitingTime = waitingTime;
   }
   
   public int getGrade()
   {
      return grade;
   }
   
   public double getWaitingTime()
   {
      return waitingTime; 
   }
}

public class RestaurantPriority
{
   public static Queue<Map.Entry<Integer, Integer>> Restaurant = new PriorityQueue<Map.Entry<Integer, Integer>>();
   public static int waitingTime = 2 + (int)(Math.random() * ((7 - 2) + 1));
   
   public static void main(String[] args)
   {
      RestaurantPriority(); 
   }
   
   public static void RestaurantPriority()
   {
      double rand = 0.0;
      boolean newCustomer = false;
      for(int i = 360; i<1440; i++)
      {
         if(Restaurant.isEmpty())
            waitingTime = 2 + (int)(Math.random() * ((7 - 2) + 1));
         if(i == 1439)
         {
            while(!Restaurant.isEmpty())
            {
               waitingTime--;
               if(waitingTime == 0)
               {
                  Restaurant.remove();
                  waitingTime = 2 + (int)(Math.random() * ((7 - 2) + 1));
               }
               System.out.println(i + ": " + Restaurant); 
               i++;
            }
         }
         rand = Math.random();
         if(rand >= 0.0 && rand < 0.2)
            newCustomer = true; 
         else
            newCustomer = false;
         if(newCustomer)
         {
            int grade = 0;
            double rand2 = Math.random();
            if(rand >= 0.0 && rand < 0.25)
               grade = 1;
            else if(rand >= 0.25 && rand < 0.5)
               grade = 2;
            else if(rand >= 0.5 && rand <0.75)
               grade = 3;
            else
               grade = 4; 
            Restaurant.add(new AbstractMap.SimpleEntry(grade,i)); 
         }
            
         if(!Restaurant.isEmpty())
         {
            waitingTime--;
            if(waitingTime == 0)
               Restaurant.poll(); 
         }
         if(!Restaurant.isEmpty() && waitingTime == 0)
         {
            waitingTime = 2 + (int)(Math.random() * ((7 - 2) + 1));
         }
         if (i<1439)
            System.out.println(i + ": " + Restaurant); 
      }
   }
}
(整个代码都写在一个文件中。我不确定这是否是相关信息,但我认为它可能会有所帮助。)

我已经为此困扰了几天,非常感谢任何帮助。

【问题讨论】:

  • 创建 PriorirtQueue 时,使用实现 Comparable 的对象创建。否则在 PriorityQueue 构造函数中传递比较器对象。在您的代码中,为什么有 Customer 类和 CustomerComparator 类? Queue&lt;Customer&gt; Restaurant = new PriorityQueue&lt;Customer&gt;(new CustomerComparator());

标签: java model hashmap queue priority-queue


【解决方案1】:
public class RestaurantPriority {

public static Queue<Customer> Restaurant = new PriorityQueue<Customer>(new CustomerComparator());
public static int waitingTime = 2 + (int) (Math.random() * ((7 - 2) + 1));

public static void main(String[] args) {
    RestaurantPriority();
}

public static void RestaurantPriority() {
    double rand = 0.0;
    boolean newCustomer = false;
    for (int i = 360; i < 1440; i++) {
        if (Restaurant.isEmpty()) {
            waitingTime = 2 + (int) (Math.random() * ((7 - 2) + 1));
        }
        if (i == 1439) {
            while (!Restaurant.isEmpty()) {
                waitingTime--;
                if (waitingTime == 0) {
                    Restaurant.remove();
                    waitingTime = 2 + (int) (Math.random() * ((7 - 2) + 1));
                }
                System.out.println(i + ": " + Restaurant);
                i++;
            }
        }
        rand = Math.random();
        if (rand >= 0.0 && rand < 0.2) {
            newCustomer = true;
        } else {
            newCustomer = false;
        }
        if (newCustomer) {
            int grade = 0;
            double rand2 = Math.random();
            if (rand >= 0.0 && rand < 0.25) {
                grade = 1;
            } else if (rand >= 0.25 && rand < 0.5) {
                grade = 2;
            } else if (rand >= 0.5 && rand < 0.75) {
                grade = 3;
            } else {
                grade = 4;
            }
            Restaurant.add(new Customer(grade, i));
        }

        if (!Restaurant.isEmpty()) {
            waitingTime--;
            if (waitingTime == 0) {
                Restaurant.poll();
            }
        }
        if (!Restaurant.isEmpty() && waitingTime == 0) {
            waitingTime = 2 + (int) (Math.random() * ((7 - 2) + 1));
        }
        if (i < 1439) {
            System.out.println(i + ": " + Restaurant);
        }
    }
}}

【讨论】:

  • 哦,我没有意识到这一点——谢谢!但是,我一直遇到的一个问题是,如果有人已经在排队,但不是学长,然后又出现了一个新的学长客户,那么即使在现有学生的等待时间还没到之前,学长就会先得到服务。然后现有的学生再次等待。我怎样才能避免这种情况——完全服务于当前学生,然后优先考虑高年级学生?
  • 我曾认为检查 waitingTime == 0 是否会有所帮助(如我的代码中所示),但显然不是这样
【解决方案2】:

您希望将客户保存在队列中而不是地图中。要让优先级队列知道如何对它们进行排序,您需要给它一个比较器。 另一种更优雅的解决方案可能是使用 Random 类而不是 Math.random()。 Random 可以为您提供具有定义上限的整数。此外,您不需要命名比较器。

附:请尝试使用 java 命名约定。 https://www.oracle.com/technetwork/java/codeconventions-135099.html

    public static void RestaurantPriority() {
        Random random = new Random();
        Queue<Customer> customers = new PriorityQueue<>(Comparator.comparingInt(o -> o.grade));
        double servingTime = 0;
        for (int i = 360; i < 1440; i++) {
            if(servingTime <= 0 && !customers.isEmpty()){
                servingTime = customers.poll().waitingTime;
            }
            if (random.nextDouble()<0.20) {
                customers.add(new Customer(
                    random.nextInt(4),
                    random.nextInt(5)+2)
                );
            }
            servingTime--;
        }
    }

【讨论】:

  • 哦,我没有意识到这一点——谢谢!但是,我一直遇到的一个问题是,如果有人已经在排队,但不是学长,然后又出现了一个新的学长客户,那么即使在现有学生的等待时间还没到之前,学长就会先得到服务。然后现有的学生再次等待。我怎样才能避免这种情况——完全服务于当前学生,然后优先考虑高年级学生?
  • 我曾认为检查 waitingTime == 0 是否会有所帮助(如我的代码中所示),但显然不是这样
  • 在您的情况下,等待时间到底是多少?我用顾客的等待时间作为餐厅满足他/她愿望的时间。这意味着如果当前正在为初级客户提供服务,高级客户不能打断。但是,如果一个大三排在第二位,然后在一天的剩余时间里每 2 分钟来一个大四生,那么大三就不会得到他的饭菜。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多