数 据 结 构 与 算 法 课 程
设
目录:
一、问题描述 **************** P 2
二、基本要求 **************** P 2
三、测试数据 **************** P 2
四、问题分析 **************** P 2
基本变量分析 *************** P 2
程序基本实现 *************** P 3
大致流程 ******************* P 3
五、核心算法 **************** P 3
总体功能实现部分 *********** P 3
随机数的取得 *********** P 3
来客判断 *************** P 4
柜台判断 *************** P 4
其他 ******************* P 5
特殊功能实现部分 *********** P 5
打票模拟模块 *********** P 5
实况模拟模块 *********** P 6
六、数据测试与运行情况 ****** P 8
七、心得体会 **************** P 13
附表 ************************ P 13
一、 问题描述:
设银行有四个服务窗口,一个等待队列, 每个窗口均可以办理存款、取款、挂失、还贷
业务,每种业务所需的服务时间不同,客户到达银行后,先到打号机上打号,号票上包括到
达时间、编号和需要办理的业务,然后在银行内等候, 当任一服务窗口空闲时,处理等候客
户中排在最前面的客户的业务。写一个上述银行业务的模拟系统,通过模拟方法求出客户在
银行内逗留的平均时间和每个窗口办理的客户数及办理的每种业务数。
二、基本要求:
每个客户到达银行的时间和需要办理的业务随机产生,输出一天客户在银行的平均逗留
时间和每个窗口每天办理的客户数和每种业务数。
*提高要求:设计图形用户界面,模拟中国银行真实的打号机操作界面,当用户选择
一种业务后,要提示用户排在前面的人数。
三、测试数据:
营业时间为 8 小时,其他模拟量自行设定。
四、问题分析:
1.基本量分析:
总体实线:线性队列,链式队列;
业务类型:随机数生成和判定;
计时器:循环控制(8:00-16:00,8h=480mins);
柜台属性:数组循环遍历;
客户:随机数生成和判定;
计数器:结构体数组/数组群;
需求变量:平均逗留时间,客户数,业务数;
数组,存放柜台剩余时间
1 号
柜台
1
编号;
业务类型;
等待时间;
到达时间;
2 号
柜台
3 号
柜台
链式队列
2.程序基本实现:
4 号
柜台
时间计数基本量:1mins(程序)= 1s(现实);
运行模式:循环(一次循环=1min);
3.大致流程(基本功能):
各变量初始化;柜台数组属性初始化;随机数初始化;客户队列初始化;
While(Time<=480)
{
if 有人:
{
客户子模块初始化,入队列;
客户数,业务数统计;
}
Switch(业务类型)
{
For 判断柜台是否空闲
空闲:客户队列队头出列;判断业务类型;改变柜台时间属性;
}
对柜台时间遍历操作(剩余时间减一)
Time++;
}
五、核心算法:
总体功能实现部分:
1.随机数的取得(#include #include)
srand() 产生种子数;
2
time() 取得系统时间;
rand()%N 取得[0,N)之间的随机数;
实际运用:
srand(time(NULL)) 以系统时间为种子数,即每秒变一次,保证程序中 rand()函数在不同时
刻运行产生结果不同;
2.来客判断
/*判断是否来人(来人几率 3/5)*/(前提 rand()%6)
if(a[Time]==1||a[Time]==2||a[Time]==4)
{
d[rear] = b[Time];//业务类型暂存入队列 d
t.EnTeam(Number,b[Time],Time,Number);//队列入队函数
rear++;
Number++;
Sum_Customers++;//总人数自增
}
3.柜台判断
/*根据业务类型判断柜台所需办理时间*/
if(d[front]!=6)//当为 6 时说明队列为空
{
for(int l=0;l<4;l++)
{
if(c[l]==0)
{
int x = 0;
x = x + +rand()%3;//在最低处理时间的基础上添加波动值
switch(d[front])//柜台 l 处理类型所需时间,同时对各业务总数操作
{
case 0:x += 4;Kind[l][0]++;Work[0]++;break;
case 1:x += 4;Kind[l][0]++;Work[0]++;break;
case 2:x += 4;Kind[l][1]++;Work[1]++;break;
case 3:x += 4;Kind[l][1]++;Work[1]++;break;
case 4:x += 10;Kind[l][2]++;Work[2]++;break;
case 5:x += 6;Kind[l][3]++;Work[3]++;break;
3
}
c[l] = x;//柜台 l 处理时间获得
front++;//队列队头后移
Sum_Time+=c[l];//总时间增加
t.OutTeam(Sum_Time);//客户队列出队
break;
}
}
4.其他
/*柜台剩余办理时间--*/
for(int n=0;n<4;n++)
{
if(c[n]>0)
{
c[n]--;
}
}
/*队列等待客户时间++*/
t.Time_Add();
特殊功能实现部分:
1.打票模拟模块:
操作解释:输入到达时间,然后选择业务,根据当前后台执行的队列情况打印
小票;
if(My_Work==1||My_Work==2||My_Work==3||My_Work==4)//判断是否是四个业务类型
Number++;
t.EnTeam(Number,My_Work-1,Time,Number);//让自己入队
t.Print_List();//打印小票函数
system("pause");
break;
{
}
else
{
4
cout<<"输入错误,请重新选择。"<
if(map[i][j]==1)
{cout<<"│";}
if(map[i][j]==2)
{cout<<"└";}
if(map[i][j]==3)
{cout<<"─";}
if(map[i][j]==4)
{cout<<"┘";}
if(map[i][j]==6)
{cout<<"Ω";}
}
cout<
I_front++;//队列头后移
}
if(c[n] == 0)//如果 n+1 号柜台没人
{
map[0][5+n*7] = 7;//把对应坐标的图像置为无人
}
六、数据测试与运行情况:
1.主界面:
2.输入 1 的效果:
3.输入 2 的效果(一):
7