模拟服务台前的排队现象问题

 模拟服务台前的排队现象问题


【问题描述】

某银行有一个客户办理业务站,在单位时间内随机地有客户到达,设每位客户的业务办理时间是某个范围内的随机值。设只有一个窗口,一位业务人员,要求程序模拟统计在设定时间内,业务人员的总空闲时间和客户的平均等待时间。假定模拟数据已按客户到达的先后顺序依次存于某个正文数据文件中。对应每位客户有两个数据,到达时间和需要办理业务的时间。

【数据描述】

typedef struct{

   int arrive;

   int treat;//客户的信息结构

}QNODE;

typedef struct node{

QNODE data;

Struct node *next;//队列中的元素信息

}LNODE

LNODE *front,*rear;// 队头指针和队尾指针



【算法描述】

{ 设置统计初值;

   设置当前时钟时间为0;

   打开数据文件,准备读;

   读入第一位客户信息于暂存变量中;

do{              //约定每轮循环,处理完一位客户

if(等待队列为空,并且还有客户){   //等待队列为空时

  累计业务员总等待时间;

  时钟推进到暂存变量中的客户的到达时间;

  暂存变量中的客户信息进队;

  读取下一位客户信息于暂存变量;

  }

  累计客户人数;

  从等待队列出队一位客户;

  将该客户的等待时间累计到客户的总等待时间;

  设定当前客户的业务办理结束时间;

  while(下一位客户的到达时间在当前客户处理结束之前){

    暂存变量中的客户信息进队;

    读取下一位客户信息于暂存变量;

   }

  时钟推进到当前客户办理结束时间;

}while(还有未处理的客户);

计算统计结果,并输出;



【C源程序】

#include<stdio.h>

#include<stdlib.h>

#define OVERFLOW -2

typedef struct{

   int arrive;

   int treat; /*客户的信息结构*/

}QNODE;

typedef struct node{

QNODE data;

struct node *next; /*队列中的元素信息*/

}LNODE;

LNODE *front,*rear;/* 队头指针和队尾指针*/

QNODE curr,temp;

char Fname[120];

FILE *fp;

void EnQueue(LNODE **hpt,LNODE **tpt,QNODE e){

/*队列进队*/

LNODE *p=(LNODE *)malloc(sizeof(LNODE));

if(!p) exit(OVERFLOW);  /*存储分配失败*/

p->data=e;

p->next=NULL;

if(*hpt==NULL) *tpt=*hpt=p;

    else *tpt=(*tpt)->next=p;

}

int DeQueue(LNODE **hpt,LNODE **tpt,QNODE *cp){

/*链接队列出队*/

LNODE *p=*hpt;

if(*hpt==NULL) return 1;/*队空*/

    *cp=(*hpt)->data;

*hpt=(*hpt)->next;

if(*hpt==NULL) *tpt=NULL;

free(p);

return 0;

}

void main()

{   int dwait=0,clock=0,wait=0,count=0,have=0,finish;

    printf("/n enter file name:");

    scanf("%s",Fname);/*输入装客户模拟数据的文件的文件名*/

    if((fp=fopen(Fname, "r"))==NULL){  /*打开数据文件*/

         printf("cannot open file %s",Fname);

         return;

     }

    front=NULL;rear=NULL;

     have=fscanf(fp, "%d%s",&temp.arrive,&temp.treat);

    do{  /*约定每轮循环,处理一位客户*/

        if(front==NULL && have==2){ /*等待队列为空,但还有客户*/

            dwait+=temp.arrive-clock; /*累计业务员总等待时间*/

clock=temp.arrive;     /*时钟推进到暂存变量中的客户的到达时间*/

            EnQueue(&front,&rear,temp); /* 暂存变量中的客户信息进队*/

            have=fscanf(fp, "%d%d",&temp.arrive,&temp.treat);

            }

        count++;                    /*累计客户人数*/

        DeQueue(&front,&rear,&curr);/*出队一位客户信息*/

wait+=clock-curr.arrive;  /*累计到客户的总等待时间*/

        finish=clock+curr.treat;/*设定业务办理结束时间;*/

        while(have==2 && temp.arrive<=finish){

       /*下一位客户的到达时间在当前客户处理结束之前*/

        EnQueue(&front,&rear,temp);/* 暂存变量中的客户信息进队*/

         have=fscanf(fp, "%d%d",&temp.arrive,&temp.treat);

        }

        clock=finish;   /* 时钟推进到当前客户办理结束时间*/

   }while(have==2 || front!=NULL);

   printf("结果:业务员等待时间%d/n客户平均等待时间%f/n",dwait,

             (double)wait/count);

   printf("模拟总时间:%d,/n客户人数:%d,/n总等待时间:%d/n",clock,

count,wait);

   getch();

}/*main_end*/’

【测试数据】

   设数据装在一个数据文件data.dat中,内容为:10 6 13 8

   显示结果为:enter file name:data.dat

结果:业务员等待时间10

客户平均等待时间1.5

模拟总时间:24,客户人数:2, 总等待时间:3
  • 22
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
客户业务分为两种, 第一种是申请从银行得到一笔资金,即取款或者借款。 第二种是向银行投入一笔资金,即存款或者还款。 Void Action() 银行有两个服务窗口,相应的有两个队列。 客户到达银行后先排第一个队。queue <int> q1; 处理每个客户业务时,如果属于第一种,且申请额超 出银行现存资金总额而得不到满足,则立即排入第二个队 queue <int> q2; 等候,直至满足时才离开银行 ;否则业务处理完后立即离开银行。 每接待完一个第二种业务的客户,则顺序检查和处理 (如果可能)第二个队列中的客户,对能满足的申请者予以满足,不能满足的者重新排到 第二个队列的队尾。 注意: 在此检查过程中,一旦银行的资金总额少于或者等于刚才第一个队列中最后一个客 户(第二种业务)被接待之的数额,或者本次已将第二个队列检查或处理了一遍,就停 止检查(因为此时已不可能还有能满足者)转而继续接待第一个队列客户。任何时刻都只 开一个窗口。假设检查不需要时间。营业时间结束时所有客户立即离开银行。 【基本要求】 利用动态存储结构实现模拟。 【测试数据】 一天营业开始时银行拥有的款额为10000(元) 初始化total=10000; ,营业时间为600(分钟)。 设定营业时间为早上9:00-晚上19:00 其他模拟参量自定,注意测定两种极端的情况:一是两个到达事件之间的间隔时间很短, 而客户的交易时间很长,另一个恰好相反,设置两个到达事件的间隔时间很长,而客户的 交易时间很短。这个有点焦虑 【实现提示】 事件有两类:到达银行的和离开银行。初始时银行现存资金总额为total。开 始营业后的第一个事件是客户到达, 设定一个计数器count来计算一天内客户人数,初始化为0 营业时间从0到closetime。到达事件发生时随机地设置 此客户的交易时间和距下一到达事件之间的时间间隔。每一个客户要办理的款额也是随机 确定的,用负值和正值分别表示第一类和第二类业务。 个人觉得用0、1、2、3分别表示取款、借款、存款、还款比较好。 变量total,closetime以及上述两个随机量的上下界均交互地从终端读入,作为模拟参数。 两个队列和一个事件表均要用动态存储结构实现。需考虑设置离开事件,以及如何设 计第二个队列的存储结构以获得较高的效率。注意:事件表是按时间顺序有序的。 void getTime();
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值