数据结构课程设计报告银行业务模拟.docx
《数据结构课程设计报告银行业务模拟.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告银行业务模拟.docx(19页珍藏版)》请在冰豆网上搜索。
数据结构课程设计报告银行业务模拟
数据结构课程设计报告
学院:
XX
专业:
XX
学生:
XX
学号:
XX
一.问题描述
题目内容:
银行业务模拟
基本要求:
设某银行有N个窗口,可同时为N位顾客办理业务。
当顾客进门时,若有窗口空闲,则可立刻办理业务,否则需要依次排队等候。
一旦有顾客业务办理完毕,派在队头的顾客便可开始办理业务。
若银行每天连续营业T小时,求一天内顾客在银行内的平均逗留时间,顾客排队等候办理业务的队列长度平均值,营业时间到点后仍需完成服务的收尾工作时间。
测试数据:
服务窗口数目N及营业时间有拥护设定,第一个顾客进门的时刻为0,之后每个顾客的进门时刻在前一个顾客进门时设定。
即在进门事件发生时随即产生两个随机数(durtime,intertime),durtime为进门顾客办理业务所需的服务时间(简称办理时间);intertime为下一个顾客将到达的时间间隔(简称时间间隔)。
R为由随机数发生器产生的随机数,顾客办理时间和顾客之间的时间间隔不妨假设与R有关,可以由下式确定:
durtime=15+R%50
intertime=2+R%10
确定的方法与实际越吻合,模拟的结果越接近现实的情况。
二.需求分析
1.程序模拟银行排队现象。
当给定窗口数及营业时间后,由随机数确定顾客办理业务及进门间隔时间,可求出一天内顾客在银行平均逗留时间,平均对长及关门后收尾工作的时间。
2.本程序由用户读入的数据仅为窗口数及营业时间,营业的时间以分钟计,窗口数及关门时间均为整型,且均大于等于1。
3.运行本程序后,得到结果为顾客数、平均等候时间、平均队长和收尾工作的时间。
仿真程序运行后屏幕输出结果应包括如下各项的模拟结果数据:
Numberofcustomer:
CustomerNum
Averagetime:
Totaltime/CustomerNum
Averagequeuelength:
Totallength/CustomerNum
Additiontime:
t-CloseTime
三.程序模块
本程序包括4个模块:
主程序模块;
实现队抽象数据类型的队模块;
实现链表抽象数据类型的链表模块;
事项银行事件抽象数据类型的银行事件模块。
各模块之间的调用关系如图所示。
主程序模块
银行事件模块
队列模块链表模块
函数调用关系图:
main
CustomerArrivedOpenFordayCustomerDeparture
EnQueueOrderInsertDeQueueQueueEmptyOrderInsert
MakeNodeMakeNode
InitQueueOrderInsertInitList
四.源程序
#include
#include
#include
#include
#defineMONEY5000//个人业务值,交易额上限
#defineOK1//离开事件1:
办理存款
#defineERROR0
#defineOVERFLOW-2
typedefintstatus;
typedefstruct{//队列1元素
intarrivetime;//到达时间
intOccurTime;//事件发生时间
intNType;//事件类型,0表示到达事件,1表示离开事件。
同时用1表示存款,2表示取款。
intduration;//办理业务时间
longintmoney;//交易金额
}Event,ElemType1;
typedefstruct{//队列2元素
intarrivetime;//到达时间
intduration;//办理业务时间
longintmoney;//交易金额
}wait,ElemType2;
typedefstructQNode1{//队列1结点类型
ElemType1data;
structQNode1*next;
}QNode1,*Queue1;
typedefstructQNode2{//队列2结点类型
ElemType2data;
structQNode2*next;
}QNode2,*Queue2;
typedefstruct{//链队列类型
Queue1front;//队头
Queue1rear;//队尾
}LinkQueue1;
typedefstruct{//链队列类型
Queue2front;//队头
Queue2rear;//队尾
}LinkQueue2;
//全局变量
longinttotal_money;//银行现存资金总额
inttotal_time;//客户逗留总时间
intuse_time;//每个顾客所用时间
intmoney;//每个顾客办理的款数
intclosetime;//银行营业时间
intINTERTIME;//下一用户到达的时间间隔
intDURATION;//办理业务所需时间
intnumber;//办理业务的次序
inttime1;//系统现在时间
LinkQueue1Q1;
LinkQueue2Q2;
Eventen;//事件
waiten1;//列表2元素
//初始化队列1
statusInitQueue1()
{Q1.front=Q1.rear=(Queue1)malloc(sizeof(QNode1));
if(!
Q1.front)exit(OVERFLOW);
Q1.front->next=NULL;
returnOK;}//初始化队列2
statusInitQueue2()
{Q2.front=Q2.rear=(Queue2)malloc(sizeof(QNode2));
if(!
Q2.front)exit(OVERFLOW);
Q2.front->next=NULL;
returnOK;}
//销毁队列1
statusdestroyqueue1()
{while(Q1.front)
{Q1.rear=Q1.front->next;
free(Q1.front);
Q1.front=Q1.rear;}
returnOK;}
//销毁队列2
statusdestroyqueue2()
{while(Q2.front)
{Q2.rear=Q2.front->next;
free(Q2.front);
Q2.front=Q2.rear;}
returnOK;}
//队列1入队列
statusEnQueue1()
{Queue1p,r,r1;
p=(Queue1)malloc(sizeof(QNode1));
if(!
p)exit(OVERFLOW);
p->data.arrivetime=en.arrivetime;
p->data.OccurTime=en.OccurTime;
p->data.NType=en.NType;
p->data.duration=en.duration;
p->data.money=en.money;
r=Q1.front->next;
while(r)
{if(p->data.arrivetimedata.arrivetime)
{if(r==Q1.front->next)
{p->next=r;
Q1.front->next=p;}
else{r1->next=p;
p->next=r;}}
r1=r;r=r->next;}
if(!
r)
{if(Q1.front->next==NULL)
{Q1.front->next=p;
Q1.rear=p;
Q1.rear->next=NULL;}
else{p->next=NULL;
Q1.rear->next=p;
Q1.rear=p;}}
returnOK;}
//队列2入队列
statusEnQueue2()
{Queue2p;
p=(Queue2)malloc(sizeof(QNode2));
if(!
p)exit(OVERFLOW);
p->data.arrivetime=en1.arrivetime;
p->data.duration=en1.duration;
p->data.money=en1.money;
p->next=NULL;
Q2.rear->next=p;
Q2.rear=p;
returnOK;}
//若队列1不空,则删除Q1的队头元素,并用en返回其值
statusDeQueue1()
{Queue1p;
if(Q1.front==Q1.rear)returnERROR;
p=Q1.front->next;
en.arrivetime=p->data.arrivetime;
en.OccurTime=p->data.OccurTime;
en.NType=p->data.NType;
en.duration=p->data.duration;
en.money=p->data.money;
Q1.front->next=p->next;
if(Q1.rear==p)Q1.rear=Q1.front;//只有一个人时
free(p);
returnOK;}
//若队列2不空,则删除Q2的队头元素,并用en1返回其值
statusDeQueue2()
{Queue2p;
if(Q2.front==Q2.rear)returnERROR;
p=Q2.front->next;
en1.arrivetime=p->data.arrivetime;
en1.duration=p->data.duration;
en1.money=p->data.money;
Q2.front->next=p->next;
if(Q2.rear==p)Q2.rear=Q2.front;//只有一个人时
free(p);
returnOK;}
//营业时间结束,全部客户离开银行
voidfree_system()
{destroyqueue1();
destroyqueue2();}
//产生随机数
statusrand_ar(int*intertime,longint*money,int*duration,int*NType)
{*intertime=rand()%INTERTIME+1;//下个客户到达的时间间隔,不大于INTERTIME
*money=rand()%MONEY+1;//每个顾客办理的款数,不大于MONEY
*duration=rand()%DURATION+1;//客户办理业务所要时间,不大于DURATION
*NType=rand()%2;//事件类型分为0和1两种
returnOK;}
voidOpenForDay(){//初始化操作
printf("请输入银行的初始存款:
");
scanf("%d",&total_money);
printf("请输入银行的营业时间(分钟):
");
scanf("%d",&closetime);
printf("请输入最大到达时间间隔(分钟):
");
scanf("%d",&INTERTIME);
printf("请输入最大的处理时间(分钟):
");
scanf("%d",&DURATION);
total_time=0;//客户逗留总时间(初始值)
number=0;//办理业务的次序(初始值)
InitQueue1();//初始化队列1
InitQueue2();//初始化队列2
en.arrivetime=0;//到达时间
en.OccurTime=0;//事件发生时间
en.NType=0;//事件类型,暂时值
en.money=0;//交易金额,暂时值
en.duration=0;//办理业务时间,暂时值
EnQueue1();//事件进队列}
//查找上一离开事件的发生时间
intfind_leave()
{Queue1p;
inti=0;
p=Q1.front->next;
while(p!
=NULL)
{if(p->data.NType!
=0)
i=p->data.OccurTime;
p=p->next;}
returni;}
voidCustomerArrived()
{intintertime;
inti;
time1=en.OccurTime;
rand_ar(&intertime,&(en.money),&(en.duration),&(en.NType));//设置一离开事件插入事件表
en.NType++;//0变1,1变2
i=find_leave();//查找上一离开事件的发生时间
if(i==0)//第一位顾客
en.OccurTime=en.arrivetime+en.duration;
else
if(i>=en.arrivetime)//本事件到达时上一事件还未离开
en.OccurTime=i+en.duration;//则此事件的离开时间=上一事件的离开时间+本事件处理时间
else//上一事件离开之后,本事件才到达
en.OccurTime=en.arrivetime+en.duration;//则此事件的离开时间=本事件到达时间+本事件处理时间
EnQueue1();//设置下一用户到达事件插入队列1
en.arrivetime=en.arrivetime+intertime;//下一客户到达时间
en.OccurTime=en.arrivetime;
en.NType=0;//暂时值
en.money=0;//暂时值
en.duration=0;//暂时值
EnQueue1();}
//返回队列2的长度
intQueueLength_q2()
{inti=0;
Queue2p;
p=Q2.front->next;
while(p)
{i++;
p=p->next;}
returni;}
//顺序检查队列2是否有满足条件者
statuscheck_q2()
{inti,j,z=0;
i=QueueLength_q2();//用i返回队列2长度
for(j=1;j<=i;j++)
{DeQueue2();//队列2出队,用en1返回其值
if(en1.money<=total_money)//若队列2出队元素的要交易的金额<=银行现存金额,则可以办理{if(time1>closetime){printf("--\t\t%d\t\t%d\t\t%d\t\t%d\t%d\n",z,use_time,number,z,(en1.arrivetime),en1.money);}
else{
time1=time1+en1.duration;//更新系统当前时间
use_time=time1-en1.arrivetime;
total_time+=use_time;//更新逗留时间
total_money-=en1.money;//更新资金总额
number++;//更新实现交易的客户数printf("%ld\t\t%d\t\t%d\t\t%d\t\t%d\t-%d\n",total_money,use_time,number,time1,(en1.arrivetime),(en1.money));}}
else{//若队列2出队元素的要交易的金额>银行现存金额,不能办理
if(time1>closetime){printf("--\t\t%d\t\t%d\t\t%d\t\t%d\t%d\n",z,use_time,number,z,(en1.arrivetime),en1.money);}
else{EnQueue2();//继续插入队列2的队尾,继续等待}}}
returnOK;}
//队列1离开事件减duration(办理业务时间)
intcut_duration(inte)//e即形参办理业务的时间
{Queue1p,q,r;
ElemType1en;
p=Q1.front->next;
r=Q1.front;
if(p)
{if(p->data.NType!
=0)
{q=p->next;
r->next=q;//删除结点
en.arrivetime=p->data.arrivetime;//到达时间
en.OccurTime=p->data.OccurTime-e;//事件发生时间
en.NType=p->data.NType;//事件类型
en.duration=p->data.duration;//办理业务时间
en.money=p->data.money;//数额
free(p);
EnQueue1();}}
returnOK;}
voidCustomerDeparture(){inti;
i=en.NType;//业务类型,1表示存款,2表示取款
time1=en.OccurTime-en.duration;
if(i==OK)//是否是办理存款
{if(en.OccurTime>closetime)//营业结束,全部客户离开银行
free_system();
else//营业时间没有结束,继续办理
{use_time=en.OccurTime-en.arrivetime;
total_time+=use_time;//更新逗留的总时间
total_money=total_money+en.money;//更新资金总额
number++;//更新服务的客户数
time1=en.OccurTime;//更新系统当前时间printf("%ld\t\t%d\t\t%d\t\t%d\t\t%d\t%d\n",total_money,use_time,number,en.OccurTime,en.arrivetime,en.money);
check_q2();//检查队列2是否有满足条件者}}
else//办理取款
{if(en.money>total_money)//办理取款,当申请金额不能满足时,离开队列1进入队列2等待
{cut_duration(en.duration);//从队列1中删除该结点
en1.arrivetime=en.arrivetime;
en1.duration=en.duration;
en1.money=en.money;
EnQueue2();//进入队列2继续等待}
else//办理取款,当能满足所申请金额时进行队列1
{if(en.OccurTime>closetime)//营业结束,全部客户离开银行
free_system();
else
{use_time=en.OccurTime-en.arrivetime;//顾客所用时间=事件发生时间-事件到达时间
total_time+=use_time;//更新逗留的总时间
total_money-=en.money;//更新资金总额
time1=en.OccurTime;//更新系统当前时间
number++;//更新客户总数printf("%ld\t\t%d\t\t%d\t\t%d\t\t%d\t-%d\n",total_money,use_time,number,en.OccurTime,en.arrivetime,en.money);}}}}
voidmain()
{cout<<"======================================"<cout<<"--------------欢迎使用银行业务模拟系统--------------"<cout<<"-----------------------------------------------------------------"<cout<<"-----------------------姓名:
钟永平-----------------------"<cout<<"************学号:
200905030325**************"<cout<<"---------------------班级:
计科3班----------------------"<cout<<"====================================="<cout<<"请选择开始或退出:
"<cout<<"1.开始银行业务模拟系统"<cout<<"0.退出程序"<intn;
cin>>n;
while(n==1)
{OpenForDay();//初始化操作
cout<<"---------------------------------------------------------------------------"<cout<<"Total_money\tuse_time\tnumber\ten.OccurTime\ten.arrivetime\tmoney"<while(Q1.front)
{DeQueue1();//队列1出队列,并用en返回值
if(en.NType==0)//en.NType等于0表示客户到达,1表示客户离开
CustomerArrived();//处理客户到达事件
else
CustomerDeparture();//处理客户离开事件,业务类型en.NType等于1表示存款,2表示取款}
printf("1.营业结