⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bank.cpp

📁 银行业务系统模拟情况
💻 CPP
字号:
// 银行业务模拟,统计最近10个客户的平均停留时间,按平均队长调整营业窗口数
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <alloc.h>
#include <dos.h>

typedef  struct {
  unsigned int  occurtime ; // 本事件发生时刻
   int  ntype ;             // 本事件类型, 0到达事件, 1~ 4各窗口离开事件
}event,elemtype;            // 事件链表结点中的数据元素类型

typedef  struct event0{     // 事件链表结点
  elemtype data;
  struct event0 *next;
}event0,*eventlist;

typedef  struct {
  unsigned int arrivaltime ;  // 该客户到达时刻
  int  duration,num ;         // 该客户处理事务耗时
}QElemType;                   // 客户队列链表结点中的数据元素类型

typedef  struct QT{           // 窗口队列链表结点
  QElemType t;
  struct QT *next;
} *linkqueue;

eventlist  ev ;       // 事件(链)表头指针
event  en ;           // 事件变量
linkqueue  q[7] ;     // 4个 客户 队列(链环,用尾指针表示)
QElemType  customer;  // 客户记录变量
long totaltime;       // 累计最近10个客户逗留时间
unsigned int  i,m=7,customernum,num0=0, // m-1是营业窗口数,离开客户数,到达客户编号
     durtime0=240, intertime0=60,       // 平均处理时间,平均到达间隔(秒)
     closetime,sum[10],s1=0;            // 终止时间,逗留时间累计区,指针
float l0;                               // 平均队列长度

void initqueu(linkqueue &r){            // 初始化队列,尾指针表示的链环。
  r=(linkqueue)malloc(sizeof(QT));
  r->next=r; r->t.duration=0;           // 头结点中(t.duration)记队列长度。
  gotoxy(1,4*i-2); printf("\n\n");
}

void enqueue(linkqueue &r,int arrt,int durt,int num){  // 入队
linkqueue r0;
  r0=(linkqueue)malloc(sizeof(QT));
  r0->t.arrivaltime=arrt; r0->t.duration=durt; r0->t.num=num;
  r0->next=r->next; r->next=r0; r=r0;  // 维护尾指针
  r->next->t.duration++;               // 维护队长度。
}

void delqueue(linkqueue &r,QElemType  &cust){
linkqueue s;
  s=r->next->next; r->next->next=s->next;
  cust=s->t; r->next->t.duration--;        // 维护队长度。
  if(s==r) r=r->next;                      // 维护尾指针
  free(s);
}

void gethead(linkqueue r,QElemType &cust){ // 取队头元素
  cust=r->next->next->t;
}
queulength(linkqueue r){                   // 队列长度
  return(r->next->t.duration);
}

void InitList(eventlist &h){              // 事件表初始化,链环
  h=(eventlist)malloc(sizeof(event0));
  h->next=h;
}

void oderinsert(eventlist h,int time,int ty){  // 插入事件表,时间有序
  eventlist p,q;
  h->data.occurtime=time+1; p=h;               // 利用监视哨查找算法
  while(time>=p->next->data.occurtime) p=p->next;
  q=(eventlist)malloc(sizeof(event0));
  q->data.occurtime=time; q->data.ntype=ty;
  q->next=p->next; p->next=q;
}

void delfirst(eventlist h,event &en){          // 截取事件表第一元素
  eventlist p;
  p=h->next; h->next=p->next; en=p->data; free(p);
}

void  openforday() {              // 系统初始化
    randomize();
    totaltime = 0;  customernum = 0;  InitList(ev); // 初始化事件队列
    oderinsert(ev,0,0);        // 设定第一客户到达事件插入事件表
    for ( i=1; i<m; ++ i) initqueu(q[i]);  // 客户队列置空
    for ( i=0; i<10; ++ i) sum[i]=0;       // 初始化逗留时间累计缓冲区
}

void random2(int &durtime,int &intertime){ // 生成随机的业务时间和到达间隔
  durtime=2*durtime0/3; durtime=durtime+random(durtime);
  intertime=random(2*intertime0);
}

minimum(linkqueue *q){     // 寻找最短队,统计平均队列长
int i,j;
  i=j=1; l0=0;
  while(i<m){
    if(q[i]->next->t.duration<q[j]->next->t.duration) j=i;
    l0 += q[i]->next->t.duration; i++;
  }  l0 /= m-1; return j;
}

void  customerarrived( ) {     // 处理客户到达事件,en.ntype 为 0
int t,durtime, intertime;
   random2(durtime, intertime); num0++;
   t = en.occurtime + intertime ;         // 下一客户到达时刻
   if(t<closetime)  oderinsert(ev,t,0); // 未到下班时间, 插入
   i = minimum(q);
   enqueue(q[i],en.occurtime,durtime,num0); // 插入短队
   if(queulength(q[i]) == 1)     // 若该客户即队头则生成下一离开事件
      oderinsert(ev, en.occurtime+durtime, i);
}

void  customerdeparture( ) {    // 处理离开事件,en.ntype > 0
    ++customernum;
    i = en.ntype ;  delqueue(q[i], customer);
    totaltime -= sum[s1];
    sum[s1]=en.occurtime - customer.arrivaltime;  // 累计逗留时间
    totaltime += sum[s1++]; s1 %= 10;
    if(l0>6&&m<7) m++;               // 根据平均队长调整营业窗口数
    if(l0<3&&m>2) m--;
    if(q[i]->next!=q[i]) {
       gethead(q[i], customer);
       oderinsert(ev, en.occurtime + customer.duration, i);
    }     // 队非空则生成下一离开事件插入事件队列, 
}
void display(){ // 显示当前(本次事件涉及的)队列,系统时间,平均间隔,离开客户数
linkqueue s;
unsigned int n;
  gotoxy(3,4*i-1); clreol(); s=q[i]->next->next;
  while(s!=q[i]->next){
    printf("%c",s->t.num%26+65); s=s->next;
  }
  gotoxy(1,1);
  printf("Sys_time %4d:%2d   Aver_intertime(\x18/\x19):%4d   Customers:%4d",
	   en.occurtime/60,en.occurtime%60,intertime0,customernum);
  gotoxy(24,25); n=totaltime/10;
  printf("  Aver_Stay_Time  %5d:%2d   Aver_Len %4.1f", n/60,n%60,l0);
  delay(100);   // 显示平均逗留时间和平均队列长度
}
void  bank_simulation() {  // 银行事务模拟
    openforday();                                       // 初始化
    while(ev->next!=ev) {
	 delfirst(ev, en);                           // 取链头事件赋 en
	 if(en.ntype == 0)  customerarrived();      // 处理客户到达事件
	 else  customerdeparture();                  // 处理客户离开事件
	 display();
	 if(kbhit()){              // 处理热键
	   if(!getch()){
	     switch(getch()){
	       case 72: if(intertime0>10) intertime0--; break;
	       case 80: intertime0++;
	       defualt:
	     }
	   }
	   else break;
	 }
     }
}

main(){
  clrscr();
  printf("\n\nPlease enter finished_time(<=1000 minute):");
  do{
    gotoxy(43,3);
    scanf("%d",&closetime);
  }while(closetime>1000||closetime<=0);
  closetime *= 60;
  bank_simulation(); return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -