一、题目与要求
1、题目
银行业务模拟与离散事件模拟
2、问题描述
假设某银行有4个窗口对外接待客户,从早晨银行开门(开门9:00am,关门5:00pm)起不断有客户进入银行。由于每个窗口在某个时刻只能接待一个客户,因此在客户人数众多时需要在每个窗口前顺次排队,对于刚进入银行的客户(建议:客户进入时间使用随机函数产生),如果某个窗口的业务员正空闲,则可上前办理业务;反之,若4个窗口均有窗户所占,他便会排在人数最少的队伍后面。
3、任务要求
(1)编制一个程序以模拟银行的这种业务活动并计算一天中客户在银行逗留的平均时间。
(2)建议有如下设置:
a) 客户到达时间随机产生,一天客户的人数设定为100人。
b) 银行业务员处理时间随机产生,平均处理时间10分钟。
(3)将一天的数据(包括业务员和客户)以文件方式输出。
二、程序设计过程
当我看到这20个题目的时候,我选择了“银行业务模拟与离散事件模拟”,因为我感觉这个做出来的话应该很好玩,当初也没有考虑太多这个选题的难易程度。
1、C语言版本
要真正的实现模拟银行办理业务必须是多线程,我开始做这个的时候Java也还没有学到多线程。所以我就用C语言模拟着写了一个。
(1)程序分析
对于银行业务模拟,首先我定义了两个结构体,一个时间结构体,用来模拟系统时间,还有一个人员结构体。
struct arrivetime //时间结构体
{
int hour;
int minute;
};
struct person //人员结构体
{
int number; //排队号码/窗口人数
int dealtime; //预计处理时间
int windowsnumber; //窗口号码
int space; //人与人之间的总间距
arrivetime waitting; //到达时间
struct person *next;
};//结构体数组
之后我把人员进来,出去的时间延时都集中在了一秒钟,每一秒钟可能生成0~100个人,每生成了一个人就通过随机数,队列随机生成他们的个人信息,每一个人进来之后这个人就要判断哪一个窗口的人最少,然后进入那个窗口排队,因为我是通过时间延时来模拟的,所以每一秒中通过遍历四个窗口的头结点,把头结点中的处理时间自减1,当处理时间为0的时候,就把它移除队列。效果图如下:
2、Java版本
因为去找老师很多次了,当我用C语言做出来的时候,说实话我感觉我这个相对于其他同学的还是蛮简单的,正好那时我们也学到了多线程,所以我就尝试着用Java写了一个初步。中途因为不知道多线程如何去实现,所以问了老师,老师和我讲了一下这个基本的思路,回寝室后我自己又查阅了很多资料。最后通过生产者和消费者思想的模式实现了多线程。对于生产者线程来说,我就只生成一个客户,然后把这个客户分配到特定的消费者线程集合之中,消费者线程中有一个集合,该集合中有数据就运行处理,否则线程休眠。
(1)基本目录
(2)运行结果
程序运行之后按开始按钮则开启生产者线程
if (e.getSource() == button) {
if (producerThread != null) {
JOptionPane.showMessageDialog(null, "客户生成线程已经启动!");
return;
}
producerThread = new Thread(new CustomerComing());
producerThread.start();
}
按暂停按钮则中断生产者线程
if (e.getSource() == button_1) {
if (producerThread == null) {
JOptionPane.showMessageDialog(null, "客户生成线程已经停止!");
return;
}
producerThread.stop();
producerThread = null;
}
三、源码
1、C语言版本
#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
//函数声明
void showmenu(); //菜单显示
void timeshow(); //时间显示
void screen(); //大厅屏幕
void serving(); //服务区
void manarrive(); //客户随机到达
void deal(struct person *p,int n); //办理业务
int compare(struct person *a,struct person *b); //判断哪个窗口人少
void deltime(struct person *p); //每个窗口第一位客户的办理时间减少
void manleave(struct person *p); //客户离开
void showarrive(struct person *p,int n); //显示客户到达信息
void showleave(struct person *p,int n); //显示客户离开信息
int sort(); //窗口排序
//结构体
struct arrivetime {
//时间结构体
int hour;
int minute;
};
struct person {
//人员结构体
int number; //排队号码/窗口人数
int dealtime; //预计处理时间
int windowsnumber; //窗口号码
int space; //人与人之间的总间距
arrivetime waitting; //到达时间
struct person *next;
};//结构体数组
struct person windows[4]= {
0,0,0,0}; //四个窗口
struct person *lastp[4];
//全局所需变量
int syshour=9; //系统时间
int sysminute=0;
int cnumber=0; //客户数目
//主函数
int main() {
char ch;
system("color f0"); //背景白色
for(int i=0; i<4; i++) {
lastp[i]=&windows[i];
windows[i].windowsnumber=i;//窗口标号
}
while(1) {
showmenu(); //过程显示
srand(time(NULL));
printf("程序正在运行中。。。\n");
printf("任意键暂停,Ese键退出\n");
Sleep(1*1000);
if(kbhit()) {
ch=getch();
if(27==ch)
break;
else
system("pause");
}
system("cls");
}
printf("程序结束!\n");
}
void showmenu() {
printf("\t银行业务模拟与离散事件模拟\n");
timeshow(); //时间显示
screen(); //大厅屏幕/客户到达/客户离开
serving(); //显示服务区
}
void timeshow() {
//时间显示
printf("\t\t时间:%d:%d\n",syshour,sysminute+1);
if(sysminute>59) {
syshour++;
sysminute=0;
} else
sysminute+=1;
}
void manarrive() {
//客户到达
//生成客户信息
struct person *newp;
newp=(struct person *)malloc(sizeof(struct person)); //客户生成
newp->number=cnumber;
newp->waitting.hour=syshour;
newp->waitting.minute=sysminute;
newp->dealtime=rand()%5+8; //处理时间为 8-12
//判断客户进入那个窗口
if(windows[0].number==0)
deal(newp,0);
else if(windows[1].number==0)
deal