我是个Java新手,请高手们帮忙看看这个程序运行结果为什么不对??

qq1212 2005-12-19 04:35:44
请高手们帮忙看看,本来这个程序应该完整实现离散事件模拟的,每次执行会自动取出队列中最小的数作为队首(本程序为时间最小者,即先到者),然后再处理事件,但不知为何现在好像不是(倒序排列了),而且事件也没处理完。
我已经焦头烂额了,请大家帮忙指正啊。谢谢!!

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();
}
}

...全文
235 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq1212 2005-12-22
  • 打赏
  • 举报
回复
谢谢大家帮忙, 我是Java新手了,所以很多东西要学习拉,编码规范今后会注意的。
现在程序倒序的问题已经解决了,余下的我自己调一下吧,努力把点菜同离开事件也模拟好。
再次表示感谢!
qq1212 2005-12-21
  • 打赏
  • 举报
回复
照API文档说明应该能够自动排好序的,且最小元素为队头,但现在不知为什么调不出啊!!
这个方法是5.0新加的
yuzl32 2005-12-21
  • 打赏
  • 举报
回复
没看过PriorityQueue文档,PriorityQueue每插入一次值它可以自动排序好内部元素吗?
masse 2005-12-21
  • 打赏
  • 举报
回复
太长了。。。自己debug一下吧
bob_thb 2005-12-21
  • 打赏
  • 举报
回复
改完了吗?
yuzl32 2005-12-21
  • 打赏
  • 举报
回复
倒过来可能是compareTo的原因
楼主模拟的不错.
醉梦书生 2005-12-21
  • 打赏
  • 举报
回复
帮你改好了,自己去看其中的改动,其实只是做了一个很小的改动,顺便说一句,楼主的代码质量真的很差,建议好好看看有关代码规范的资料(你的错误也是由于你的代码不规范造成的),好好学习吧
醉梦书生 2005-12-21
  • 打赏
  • 举报
回复

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();
}
}

醉梦书生 2005-12-21
  • 打赏
  • 举报
回复
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
qq1212 2005-12-20
  • 打赏
  • 举报
回复
各位帮帮忙拉!!!

62,629

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧