请高手们帮忙看看,本来这个程序应该完整实现离散事件模拟的,每次执行会自动取出队列中最小的数作为队首(本程序为时间最小者,即先到者),然后再处理事件,但不知为何现在好像不是(倒序排列了),而且事件也没处理完。
    我已经焦头烂额了,请大家帮忙指正啊。谢谢!!ps:本程序用到了JavaSE 5.0 新添加的数据结构——优先队列(PriorityQueue)import java.util.*;/**
 *本类定义顾客群,把到达的几人/批的顾客作为一个整体看待。
 *
 */
class customerGroup
{
//定义每批的顾客人数,用随机数产生人数
public final int groupsize = (int)(Math.random()*4 + 1);

//定义每批顾客点的餐点数,随机数产生
public int orderSize()
{
int scoops = 0;

for (int i = 0;i < groupsize;i++)
scoops += (int)(Math.random()*2 + 1); return scoops;
}
}/**
 *定义抽象类event,即要插入优先队列的类型,
 *将整体事件作为一个整体处理
 */
abstract class event implements Comparable
{
public int time;
public customerGroup group = new customerGroup();;
storeSimulation store = new storeSimulation();

event(){}

//初始构造
event(int t, customerGroup g)
{
time = t;
group = g;
}

//本来事件类无法比较(优先队列要能比较的对象才能插入,否则出错),
//定义此方法为了使插入队列的event类型能用顾客到达的时间先后来比较
public int compareTo(Object other)
{
return new Integer(time).compareTo(new Integer(((event)other).time));
}

//抽象类靠arriveEvent,orderEvent,leaveEvent实现
public abstract void processEvent();
}
/**
 *定义优先队列,能将event类插入并进行比较时间
 */
class simulation
{
public boolean done;
protected PriorityQueue<event> eventQueue = new PriorityQueue<event>();
protected int time;

//将插入队列的事件处理
public void run()
{
done = eventQueue.isEmpty();//队列非空 while(!done)
{
event nextEvent = eventQueue.poll();//检索队首元素
time = nextEvent.time;//取出时间方便currentTime中输出时间
nextEvent.processEvent();//处理事件

//队列空,事件处理完毕,结束循环
if(eventQueue.isEmpty()) 
done = true; 
}
}

public int currentTime()
{
return time;
}

public void scheduleEvent(event newEvent)
{
eventQueue.add(newEvent);
}
}class storeSimulation extends simulation
{
public int freeChairs = 50;//座位数
private double profits;

public void order (int numberOfScoops)
{
//freeChairs = numberOfScoops;
}
}//到达事件
//实现抽象类event的方法processEvent()
class arriveEvent extends event
{
public int time;

arriveEvent(int t, customerGroup g)
{
time = t;
group = g;
}

//实现抽象类,完成顾客到达,并判断是否有座
public void processEvent()
{
System.out.println("customer group of size " + group.groupsize + " arrives at time " + time);

//有座
if (group.groupsize < store.freeChairs) 
{
//座位减少
store.freeChairs -= group.groupsize;
//初始化点菜事件,时间随机推进
event oe = new orderEvent(time + (int)(Math.random()*8 + 2), group);
//将点菜事件插入队列
store.scheduleEvent(oe);
}
else
System.out.println("no space:group leaves");
}
}//点菜事件
class orderEvent extends event
{ public int time;

orderEvent(int t, customerGroup g)
{
time = t;
group = g;
}

//点菜,吃饭
public void processEvent()
{
int scoops = group.orderSize();

System.out.println("customer group of size " + group.groupsize +
 " order " + scoops + " scoops of ice cream at time " + time); store.order(scoops);
//初始化离开事件,时间随机推进
event le = new leaveEvent(time + (int)(Math.random()*20 +15), group);
//将离开事件插入队列
store.scheduleEvent(le);
}
}//离开事件
class leaveEvent extends event
{
public int time;

leaveEvent(int t, customerGroup g)
{
time = t;
group = g;
}

//吃完走人
public void processEvent()
{

System.out.println("customer group size " + group.groupsize
    + " leaves at time " + time);
//空出坐位
store.freeChairs += group.groupsize;
}
}//main方法所在类,实现整个事件
public class store
{
public int time;
public customerGroup group;
public storeSimulation stores;

//构造事件
public void RestaurantSimulation()
{
stores = new storeSimulation();

//餐馆工作60分钟,按随机时间到达一批顾客群
for (time = 0; time < 60; time += (int)(Math.random()*3 + 2))
{
//产生新顾客群
group = new customerGroup();
//初始化到达事件,判断是否有座,时间随机推进
event ae = new arriveEvent(time,group);
//将到达事件插入队列
stores.scheduleEvent(ae);
}


/**
 *开始处理事件,将插入的到达事件从队列中取出,根据座位空否判断是否继续处理点菜、离开事件。
 *问题所在:本来该打印出点菜等事件,但实际只输出到达事件,且逆序排列,按照API中优先队列
 *的说明,应该自动取出队列中最小的数作为队首(本程序为时间最小者,即先到者),但不知为何
 * 好像不是,且事件也没处理完,请高手们帮忙修改指正
 **/
stores.run();
}

public static void main(String args[])
{
store s = new store();
s.RestaurantSimulation();
}
}

解决方案 »

  1.   

    没看过PriorityQueue文档,PriorityQueue每插入一次值它可以自动排序好内部元素吗?
      

  2.   

    照API文档说明应该能够自动排好序的,且最小元素为队头,但现在不知为什么调不出啊!!
    这个方法是5.0新加的
      

  3.   

    return new Integer(time).compareTo(new Integer(((event)other).time));
    比较的结果是什么?刚好倒过来的吧?也许这就是你的原因所在:
    compareTo
    public int compareTo(Integer anotherInteger)
    Compares two Integer objects numerically. Specified by:
    compareTo in interface Comparable<Integer>
    Parameters:
    anotherInteger - the Integer to be compared. 
    Returns:
    the value 0 if this Integer is equal to the argument Integer; a value less than 0 if this Integer is numerically less than the argument Integer; and a value greater than 0 if this Integer is numerically greater than the argument Integer (signed comparison).
    Since: 
    1.2 
      

  4.   


     package testAll; import java.util.*; /**
      *本类定义顾客群,把到达的几人/批的顾客作为一个整体看待。
      *
      */
     class customerGroup
     {
      //定义每批的顾客人数,用随机数产生人数
      public final int groupsize = (int)(Math.random()*4 + 1);
     
      //定义每批顾客点的餐点数,随机数产生
      public int orderSize()
      {
      int scoops = 0;
     
      for (int i = 0;i < groupsize;i++)
      scoops += (int)(Math.random()*2 + 1);  return scoops;
      }
     } /**
      *定义抽象类event,即要插入优先队列的类型,
      *将整体事件作为一个整体处理
      */
     abstract class event implements Comparable
     {
      public int time;
      public customerGroup group = new customerGroup();;
      storeSimulation store = new storeSimulation();
     
      event(){}
     
      //初始构造
      event(int t, customerGroup g)
      {
      time = t;
      group = g;
      }
     
      //本来事件类无法比较(优先队列要能比较的对象才能插入,否则出错),
      //定义此方法为了使插入队列的event类型能用顾客到达的时间先后来比较
      public int compareTo(Object other)
      {
      return new Integer(time).compareTo(new Integer(((event)other).time));
      }
     
      //抽象类靠arriveEvent,orderEvent,leaveEvent实现
      public abstract void processEvent();
     }
     /**
      *定义优先队列,能将event类插入并进行比较时间
      */
     class simulation
     {
      public boolean done;
      protected PriorityQueue<event> eventQueue = new PriorityQueue<event>();
      protected int time;
     
      //将插入队列的事件处理
      public void run()
      {
      done = eventQueue.isEmpty();//队列非空  while(!done)
      {
      event nextEvent = eventQueue.poll();//检索队首元素
      time = nextEvent.time;//取出时间方便currentTime中输出时间
      nextEvent.processEvent();//处理事件
     
      //队列空,事件处理完毕,结束循环
      if(eventQueue.isEmpty()) 
      done = true; 
      }
      }
     
      public int currentTime()
      {
      return time;
      }
     
      public void scheduleEvent(event newEvent)
      {
      eventQueue.add(newEvent);
      }
     } class storeSimulation extends simulation
     {
      public int freeChairs = 50;//座位数
      private double profits;
     
      public void order (int numberOfScoops)
      {
      //freeChairs = numberOfScoops;
      }
     }// 到达事件
    // 实现抽象类event的方法processEvent()
     class arriveEvent extends event
     {
      public int time;
     
      arriveEvent(int t, customerGroup g)
      {
      super(t, g);
      time = t;
      group = g;
      }
     
      //实现抽象类,完成顾客到达,并判断是否有座
      public void processEvent()
      {
      System.out.println("customer group of size " + group.groupsize + " arrives at time " + time);
     
      //有座
      if (group.groupsize < store.freeChairs) 
      {
      //座位减少
      store.freeChairs -= group.groupsize;
      //初始化点菜事件,时间随机推进
      event oe = new orderEvent(time + (int)(Math.random()*8 + 2), group);
      //将点菜事件插入队列
      store.scheduleEvent(oe);
      }
      else
      System.out.println("no space:group leaves");
      }
     }// 点菜事件
     class orderEvent extends event
     {  public int time;
     
      orderEvent(int t, customerGroup g)
      {
      super(t, g);
      time = t;
      group = g;
      }
     
      //点菜,吃饭
      public void processEvent()
      {
      int scoops = group.orderSize();
     
      System.out.println("customer group of size " + group.groupsize +
       " order " + scoops + " scoops of ice cream at time " + time);  store.order(scoops);
      //初始化离开事件,时间随机推进
      event le = new leaveEvent(time + (int)(Math.random()*20 +15), group);
      //将离开事件插入队列
      store.scheduleEvent(le);
      }
     }// 离开事件
     class leaveEvent extends event
     {
      public int time;
     
      leaveEvent(int t, customerGroup g)
      {
      super(t, g);
      time = t;
      group = g;
      }
     
      //吃完走人
      public void processEvent()
      {
     
      System.out.println("customer group size " + group.groupsize
          + " leaves at time " + time);
      //空出坐位
      store.freeChairs += group.groupsize;
      }
     }// main方法所在类,实现整个事件
     public class Store
     {
      public int time;
      public customerGroup group;
      public storeSimulation stores;
     
      //构造事件
      public void RestaurantSimulation()
      {
      stores = new storeSimulation();
     
      //餐馆工作60分钟,按随机时间到达一批顾客群
      for (time = 0; time < 60; time += (int)(Math.random()*3 + 2))
      {
      //产生新顾客群
      group = new customerGroup();
      //初始化到达事件,判断是否有座,时间随机推进
      event ae = new arriveEvent(time,group);
      //将到达事件插入队列
      stores.scheduleEvent(ae);
      }
     
     
      /**
       *开始处理事件,将插入的到达事件从队列中取出,根据座位空否判断是否继续处理点菜、离开事件。
       *问题所在:本来该打印出点菜等事件,但实际只输出到达事件,且逆序排列,按照API中优先队列
       *的说明,应该自动取出队列中最小的数作为队首(本程序为时间最小者,即先到者),但不知为何
       * 好像不是,且事件也没处理完,请高手们帮忙修改指正
       **/
      stores.run();
      }
     
      public static void main(String args[])
      {
      Store s = new Store();
      s.RestaurantSimulation();
      }
     }
      

  5.   

    倒过来可能是compareTo的原因
    楼主模拟的不错.
      

  6.   

    谢谢大家帮忙, 我是Java新手了,所以很多东西要学习拉,编码规范今后会注意的。
    现在程序倒序的问题已经解决了,余下的我自己调一下吧,努力把点菜同离开事件也模拟好。
    再次表示感谢!