//银行业务管理系统
/*银行业务模拟
问题描述
假设某银行有4个窗口对外接待客户,从早晨银行开门(开门9:00am,关门5:00pm)起不断有客户进入银行。由于每个窗口在某个时刻只能接待一个客户,因此在客户人数众多时需要在每个窗口前顺次排队,对于刚进入银行的客户(建议:客户进入时间使用随机函数产生),如果某个窗口的业务员正空闲,则可上前办理业务;反之,若4个窗口均有窗户所占,他便会排在人数最少的队伍后面。
任务要求:
1) 编制一个程序以模拟银行的这种业务活动并计算一天中客户在银行逗留的平均时
间。
2) 建议有如下设置:
a) 客户到达时间随机产生,一天客户的人数设定为100人。
b) 银行业务员处理时间随机产生,平均处理时间10分钟。
3) 将一天的数据(包括业务员和客户)以文件方式输出。
*/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define OK 1
#define ERROR 0
#define WINDOWS_NUM 4
#define MAXSIZE 200
typedef int Status;
//时间结点
typedef struct
{
int hour; //时
int minite; //分
int time; //顾客进银行的时间距9:00的分钟数
}TNode;
//顾客结点
typedef struct
{
TNode comeTime; //进来时间
TNode outTime; //出去时间
int stayTime; //办理时间
int waitTime; //等待时间
}ElemType;
//初始顾客
typedef ElemType *Customers; //初始客户
//队列结点 ! 建循环队列
typedef struct
{
ElemType *base;
int maxsize;
int rear,front;
}Queue;
//窗口
typedef Queue *Windows;
//初始化
Status InitQueue(Queue &Q)
{
Q.base=(ElemType*)malloc(sizeof(ElemType)*(MAXSIZE+2));
Q.maxsize=MAXSIZE;
Q.rear=Q.front=0;
return OK;
}
//判队列满
bool QueueFull(Queue Q)
{
if((Q.rear+1)%MAXSIZE == Q.front) return 1;
return 0;
}
//判队列空
bool QueueEmpty(Queue Q)
{
if(Q.rear == Q.front) return 1;
return 0;
}
//返回队列长度
int QueueLength(Queue Q){ return (Q.rear-Q.front+MAXSIZE)%MAXSIZE; }
//入队
Status In(Queue &Q,ElemType e)
{
if(QueueFull(Q))
{
ElemType *p=(ElemType*)realloc(Q.base,2*MAXSIZE);
if(!p) { printf("ReNew Error!\n"); exit(0); }
Q.base=p;
}
Q.base[Q.rear]=e;
printf("\t进来时间:%.2d:%.2d\t",e.comeTime.hour,e.comeTime.minite);
printf("办理需要时间:%d\n",e.stayTime);
Q.rear=(Q.rear+1)%MAXSIZE;
return OK;
}
//出队
int Out(Queue &Q,ElemType &e)
{
if(QueueEmpty(Q)) { printf("Queue Empty!\n"); exit(0); }
e=Q.base[Q.front];
printf("\t\t进来时间:%.2d:%.2d\t",e.comeTime.hour,e.comeTime.minite);
printf("\t\t出去时间: %.2d:%.2d\n",e.outTime.hour,e.outTime.minite);
printf("\t\t逗留时间:%d\n",e.waitTime);
Q.front=(Q.front+1)%MAXSIZE;
return e.waitTime;
}
//产生 0 - 1000 之内的随机数
int produce_randomTime() {return rand()%1000;}
//初始化顾客来的时间
int InitCustomerTime(TNode &T)
{
int h=produce_randomTime()%8;
int m=produce_randomTime()%60;
T.hour=9+h;
T.minite=m;
T.time=(h-5)*60+m;
int sum=h*60+m;
return sum;
}
//输出所有初始顾客
Status PrintAllCustomers(Customers Q)
{
for(int i=0;i<MAXSIZE;i++)
{
TNode come=Q[i].comeTime;
printf("%3.2d. cometime:%.2d:%.2d\t transactTime:%2d\ttime:%d\n",i+1,come.hour,come.minite,Q[i].stayTime,come.time);
}
return OK;
}
//输出出银行的顾客
Status PrintOutCustomer(Customers Q)
{
for(int i=0;i<MAXSIZE;i++)
{
TNode out=Q[i].outTime;
printf("%3.2d. OutTime:%.2d:%.2d\ttime:%d\n",i,out.hour,out.minite,out.time);
}
return OK;
}
//初始化 MAXSIZE 个顾客
Status InitAllCustomer(Customers &I)
{
I=(ElemType*)malloc(sizeof(ElemType)*MAXSIZE);
for(int i=0;i<MAXSIZE;i++)
{
int transact=produce_randomTime();
I[i].comeTime.time=InitCustomerTime(I[i].comeTime);
I[i].stayTime=transact%10+1;
I[i].outTime.hour=I[i].outTime.minite=I[i].outTime.time=0;
I[i].waitTime=0;
}
PrintAllCustomers(I);
printf("已初始化顾客,可以开始演示...\n");
printf("\n");
system("pause");
return OK;
}
//初始化窗口
Status InitWindows(Windows &Ws)
{
Ws=(Queue*)malloc(sizeof(Queue)*WINDOWS_NUM);
for(int i=0;i<WINDOWS_NUM;i++) InitQueue(Ws[i]);
return OK;
}
/******************* 银行工作 *************************************/
bool *visit;
//遍历寻找 T 时刻进来时刻的顾客
int FindCustomer(int time,Customers Ct,int a[MAXSIZE])
{
int count=0;
for(int i=0;i<MAXSIZE;i++)
{
if(!visit[i] && time == Ct[i].comeTime.time)
{
a[count++]=i;
visit[i]=1;
}
}
return count;
}
//找队长最短的队
int FindQueue(Windows &Ws)
{
int min=200,index=0;
for(int i=0;i<WINDOWS_NUM;i++)
{
if(min>QueueLength(Ws[i]))
{
min=QueueLength(Ws[i]);
index=i;
}
}
return index;
}
//顾客办理,时间流逝中 在每个窗口的队头办理时间--
Status ClientsTransact(Windows &Ws)
{
printf("办理中:\n");
printf("___________________________\n");
printf("窗口\t队长度\t已经等待\n");
for(int i=0;i<WINDOWS_NUM;i++)
{
printf("%2d",i+1);
int num=Ws[i].front;
if(!QueueEmpty(Ws[i]))
{
Ws[i].base[num].stayTime--;
printf("\t%3d",QueueLength(Ws[i]));
printf("\t ");
for(int j=0;j<QueueLength(Ws[i]);j++,num++)
printf(" %2d",Ws[i].base[num].waitTime++);
}
printf("\n");
}
printf("___________________________\n");
return OK;
}
//办理结束,出队 在每个窗口的队头的还需办理时间减为0时,出队
int ClientsOut(Windows &Ws)
{
int s=0;
ElemType e;
printf("___________________________\n");
printf("办理完出队:\n");
for(int i=0;i<WINDOWS_NUM;i++)
{
int num=Ws[i].front;
if(!QueueEmpty(Ws[i]) && Ws[i].base[num].stayTime==0)
{
int Time=Ws[i].base[num].outTime.time=Ws[i].base[num].waitTime+Ws[i].base[num].comeTime.time;
Ws[i].base[num].outTime.hour=Time/60+9;
Ws[i].base[num].outTime.minite=Time%60;
printf("来自第 %d 个窗口\n",i+1);
s+=Out(Ws[i],e);
}
}
printf("___________________________\n");
return s;
}
//输出窗口队伍
Status PrintQueue_Status(Windows Ws,int nowtime)
{
printf("__________________________________\n");
printf("队伍状态显示:\t");
printf("现在时间:%.2d:%.2d\t已过时间:%d\n",nowtime/60+9,nowtime%60,nowtime);
printf("_____________________________________________________________\n");
printf("\t顾客\t进来时间 办理还需时间\t已等待\n");
for(int i=0;i<WINDOWS_NUM;i++)
{
int l=QueueLength(Ws[i]);
printf("窗口%d : %2d",i+1,l);
int b=Ws[i].front,end=Ws[i].rear;
ElemType e=Ws[i].base[b];
while(b!=end)
{
printf("\t %.2d:%.2d\t\t%d\t%3d\n\t",e.comeTime.hour,e.comeTime.minite,e.stayTime,e.waitTime-1);
b=(b+1)%MAXSIZE;
}
printf("\n");
}
printf("_____________________________________________________________\n");
return OK;
}
//银行开门开始工作
Status BankOpen(Windows &Ws,Customers &Ct)
{
double sum=0;
visit=(bool*)malloc(sizeof(bool)*MAXSIZE);
for(int i=0;i<MAXSIZE;i++) visit[i]=0;
for(int timer=0;timer<=480;timer++)
{
int now[MAXSIZE];
int num=FindCustomer(timer,Ct,now);
printf("_______________________________\n");
if(num) printf("进来 %d 个顾客.",num);
else printf("没有顾客进来.");
printf("\t\t计时器:%d\n",timer);
for(int i=0;i<num;i++)
{
printf("第%d个",i+1);
int min=FindQueue(Ws);
In(Ws[min],Ct[now[i]]);
}
printf("_______________________________\n");
// system("pause");
ClientsTransact(Ws); //办理
// system("pause");
PrintQueue_Status(Ws,timer);
// system("pause");
sum+=ClientsOut(Ws); //出队,处理
}
// PrintOutCustomer(Ct);
printf("\n到17:00\t下班......\n");
printf("平均逗留时间:%2.2f\n",sum*1.0/100);
return OK;
}
/***********************************************/
//主函数
int main()
{
srand(time(NULL)); //初始化随机数种子
Customers Clients;
InitAllCustomer(Clients); //初始化顾客
Windows Ws;
InitWindows(Ws); //初始化窗口
BankOpen(Ws,Clients); //银行开张
system("pause");
return 0;
}