银行业务模拟

来源:互联网 发布:mac安装aptget 编辑:程序博客网 时间:2024/05/12 23:03
typedef struct ListNode{    int occurtime;//事件发生的时间int type;//0-到达 1-1号窗口离开 2-2号窗口离开 3-3号窗口离开 4-4号窗口离开ListNode* next;}ListNode,*pListHead;typedef struct QueneNode{int arrivetime;   //客户的到达时间int duration;     //客户处理业务的时间长度QueneNode* next;}QueneNode;typedef struct Quene{QueneNode* pQueneHead;QueneNode* pQueneTail;int length;}Quene;class Bank{public:Bank(void);~Bank(void);void init();int random(int& a,int& b);   //产生客户的到达时间和业务办理时间int arrive();int leave();int monitor();int initList();int insertListInOrder(pListHead& phead,ListNode listnode);int deleteListHead(pListHead& phead);int isEmptyList(pListHead phead);int initQuene(Quene& myQuene);int insertQuene(Quene& myQuene,QueneNode quenenode);int judgeShortestQuene();int delQueneHead(Quene& myQuene);int isEmptyQuene(Quene& myQuene);private:Quene windowQuene[4];  //4个窗口队列pListHead myList; //事件链表的头指针ListNode ListHeadElement; //链表的头元素QueneNode QueneHeadElement;//队列的头元素int count;     //客户人数统计int totalTime; //总时间统计int arrivaltime_;   //客户到达时间int businesstime_;  //客户业务办理时长};
#include "Bank.h"#include "stdlib.h"#include "stdio.h"#define KHJG 5 /* 两相邻到达的客户的时间间隔最大值 */#define BLSJ 30 /* 每个客户办理业务的时间最大值 */#define CLOSETIME 8*60 //银行的开门时长,单位:分钟Bank::Bank(void){}Bank::~Bank(void){}void Bank::init(){count = 0;totalTime = 0;arrivaltime_ = 0;businesstime_ = 0;//创建事件链表,并将第一个客户到达事件加入链表initList();//初始化4个窗口队列for(int i=0;i<4;i++){initQuene(windowQuene[i]);}}int Bank::arrive(){//客户到达,排队并处理++count;int i = judgeShortestQuene();QueneNode customer;customer.arrivetime = arrivaltime_;customer.duration = businesstime_;customer.next = NULL;insertQuene(windowQuene[i],customer);printf("第%d位顾客到达第%d个窗口\n",count,i+1);if(windowQuene[i].length == 1){ListNode leave;leave.next = NULL;leave.occurtime = arrivaltime_+ businesstime_;leave.type = i+1;      //0-到达 1-1号窗口离开 2-2号窗口离开 3-3号窗口离开 4-4号窗口离开insertListInOrder(myList,leave);}//产生下一客户到达时间及业务办理时长random(arrivaltime_,businesstime_);//构造下一客户到达事件并插入有序事件表ListNode nextarrive;nextarrive.next =NULL;nextarrive.occurtime = arrivaltime_;nextarrive.type = 0;if(arrivaltime_ < CLOSETIME){insertListInOrder(myList,nextarrive);}return 0;}int Bank::leave(){    //判断是哪个窗口有人离开int i = ListHeadElement.type;delQueneHead(windowQuene[i-1]);//计算这个顾客的耗时totalTime += ListHeadElement.occurtime - QueneHeadElement.arrivetime;printf("窗口%d有客户离开\n",i);//队头的人办理完业务离开后就可以知道下一个人什么时候离开了if(!isEmptyQuene(windowQuene[i-1])){ListNode leave;leave.next = NULL;leave.occurtime = windowQuene[i-1].pQueneHead->next->duration + ListHeadElement.occurtime;leave.type = i;insertListInOrder(myList,leave);}return 0;}int Bank::monitor(){init();while(!isEmptyList(myList)){deleteListHead(myList);if(ListHeadElement.type == 0)arrive();elseleave();}printf("顾客总数:%d, 所有顾客共耗时:%d分钟, 平均每人耗时: %d分钟\n",count,totalTime,totalTime/count);return 0;}int Bank::initList(){   random(arrivaltime_,businesstime_);   myList = (ListNode*)malloc(sizeof(ListNode));   myList->occurtime = arrivaltime_;   myList->type = 0;   myList->next = NULL;   return 0;}int Bank::insertListInOrder(pListHead& phead,ListNode listnode){ListNode* pNewNode = (ListNode*)malloc(sizeof(ListNode));if(pNewNode == NULL){printf("error when malloc QueneNode!\n");return -1;}pNewNode->next = NULL;pNewNode->occurtime = listnode.occurtime;pNewNode->type = listnode.type;if(phead == NULL){phead = pNewNode;}else{if(pNewNode->occurtime <= phead->occurtime){pNewNode->next = phead;myList = pNewNode;}else{ListNode* ptemp = phead;ListNode* pfront = NULL;while(pNewNode->occurtime > ptemp->occurtime){pfront = ptemp;ptemp = ptemp->next;if(ptemp ==NULL)          //说明应该插在链表尾部.break;}pfront->next = pNewNode;pNewNode->next = ptemp;}}}int Bank::deleteListHead(pListHead& phead){if(phead == NULL){printf("error when deleteListHead!empty list!\n");return -1;}ListNode* temp = phead;phead = temp->next;//把删除的头节点的信息存起来。因为我们需要知道离开事件发生时他的发生时间以及哪个窗口发生的。ListHeadElement.occurtime = temp->occurtime;ListHeadElement.type = temp->type;free(temp);temp =NULL;}int Bank::isEmptyList(pListHead phead){     if(phead == NULL) return 1; else  return 0;}int Bank::random(int& arrivaltime,int& businesstime){arrivaltime += 1+rand()%KHJG;businesstime = rand()%BLSJ;return 0;}//返回窗口号(注意是0,1,2,3不是1,2,3,4)int Bank::judgeShortestQuene(){int temp = windowQuene[0].length;int windowNum = 0;for(int i=1;i<4;i++){if(temp > windowQuene[i].length){temp = windowQuene[i].length;windowNum = i;}}return windowNum;}int Bank::initQuene(Quene& myQuene){myQuene.pQueneHead = myQuene.pQueneTail =(QueneNode*)malloc(sizeof(QueneNode));if(myQuene.pQueneHead == NULL){printf("initQuene error!\n");return -1;}myQuene.length = 0;myQuene.pQueneTail->next =NULL;return 0;}int Bank::insertQuene(Quene& myQuene,QueneNode quenenode){QueneNode* pNewNode = (QueneNode*)malloc(sizeof(QueneNode));if(pNewNode == NULL){printf("error when malloc QueneNode!\n");return -1;}pNewNode->arrivetime = quenenode.arrivetime;pNewNode->duration = quenenode.duration;pNewNode->next = NULL;myQuene.pQueneTail->next = pNewNode;myQuene.pQueneTail = pNewNode;++myQuene.length;return 0;}int Bank::isEmptyQuene(Quene& myQuene){if(myQuene.length == 0)return 1;else return 0;}int Bank::delQueneHead(Quene& myQuene){if(isEmptyQuene(myQuene)){printf("error!quene is empty!\n");return -1;}QueneNode* temp = myQuene.pQueneHead->next;myQuene.pQueneHead->next = temp->next;if(myQuene.length =1)                        //如果删掉的是队尾,要改变尾指针{myQuene.pQueneTail = myQuene.pQueneHead;}--myQuene.length;    QueneHeadElement.arrivetime = temp->arrivetime;QueneHeadElement.duration = temp->duration;free(temp);temp = NULL;}