银行排队问题

事件驱动模拟问题

问题分析

​ 银行开放了4个窗口,现在客户要从四面八方到银行办理业务;根据常识,到银行就少不了排队。我们排队按最短队伍排列,中途不切换队伍。

​ 现在随机生成到银行办理业务的人之间的 时间差 i n n n e r t i m e innnertime innnertime ,和办理业务所需的时间 d u r t i m e durtime durtime。完成事件链的模拟和三个队列的模拟,并计算每个人在银行的 平均逗留时间

注意

  1. 逗留事件不等于办理业务的时间,等于排队时间 + 办理业务时间;

  2. 事件有序链表

    按照 OccurTime 顺序排列;

  3. 四个队列结构图

  4. 队列里是客户,事件列表里是客户的两个时间(到达/离开)。

数据处理

  1. 对于时间类型分成四种:

    EType 事件类型
    0 到达银行
    N > 0 由 n n n 号窗口离开
  2. 队列链表数据结构处理如图所示。

处理流程

蓝色 计算平均逗留时间;

红色 、绿色 代表不同的客户;

  1. 初始化银行里新的一天~

    定义事件链表、窗口队列数组、累计客户逗留时间、累计客户数;

    为了方便处理,在事件链表中加入一个 0 时间的客户到达操作;

  2. 取出事件队列里的事件,处理不同的事件类型;

    1. 处理到达 客户到达事件

      1. 首先,用户数量增加1

      2. 取到随机数(题目处理的随机数是有原因的)DurTime innerTime 业务处理和间隔时间

      3. 本次随机数的 客户的到达事件,也就是本客户到达事件之后的客户加入 到事件链表中;

      4. 选择长度最小的队列,本次 客户 加入到队列中;

      5. 如果队列中有且仅有 1 个 客户,那么我们把这个 客户的离开事件加入到事件列表里;在队列里删除;

        为什么

        如果这个队列大于1,那么说明前面有更多的客户离开事件需要处理,

        按流程来说,我们的客户也是不需要离开的。

        只有这个队列是 1 个人的时候,我们才可以用已知的 客户到达事件 发生时间 计算客户离开发生时间。 (到达时间 + 事务处理时间即可)。

    2. 处理 客户离开事件离开事件

      1. 首先选择出正确的 队列,取出队列首元素并删除;
      2. 用户总时间,离开时间减去到达时间;
      3. 判断此队列中是否有 需要离开的客户; 队列不为空,取出队列首元素,把该事件加入到事件列表中;离开事件发生时间是 此事件发生时间 + 客户的durtime

代码:

/*************************************************************************> File Name: main.cpp> Author: > Mail: zhang_ze_mail@163.com> Created Time:  ************************************************************************/#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <queue>
#include <list>
#include <unistd.h>
#include <time.h>
using namespace std;#define P_W_R(a, ...)  printf("\033[1m\033[43;31m" a "\033[0m", ## __VA_ARGS__);
#define P_B_R(a, ...)  printf("\033[1m\033[40;31m" a "\033[0m", ## __VA_ARGS__);
#define P_W_G(a, ...)  printf("\033[1m\033[43;32m" a "\033[0m", ## __VA_ARGS__);
#define P_B_G(a, ...)  printf("\033[1m\033[40;32m" a "\033[0m", ## __VA_ARGS__);
#define P_B_Y(a, ...)  printf("\033[1m\033[40;33m" a "\033[0m", ## __VA_ARGS__);
//#define P_B_R(args...) printf("\033[40;31m%s\033[0m", #args);struct Event {int OccurTime;int NType;
};struct QEvent {int ArrivalTime;int durtime;
};list<Event> ev;
queue<QEvent> q[5];
int TotalTime, CustomerNum;
const int CloseTime = 1000; // bank will close ~bool cmp(Event a, Event b) {return a.OccurTime < b.OccurTime;
}void EventOrderInsert(list<Event> &ev, Event en, bool (*cmp)(Event, Event)) {if (ev.empty()) {ev.push_back(en);return ;}int flag = 0;for (auto it = ev.begin(); it != ev.end(); it++) {if(!cmp((*it), en)) {ev.insert(it, en);flag = 1;break;}} if (flag == 0) ev.push_back(en);return ;
}void OpenForDay() {TotalTime = 0, CustomerNum = 0; Event en; // 设定第一个客户;en.OccurTime = 0, en.NType = 0;EventOrderInsert(ev, en, cmp); //插入事件// 如果多次调用,队列置为空
}void Random(int &a, int &b) {srandom(time(0));a = random() % 300;b = random() % 300;return ;
}int MinNum() {int j = 1;for (int i = 1; i <= 4; i++) {if (q[i].size() < q[j].size()) j = i;}return j;
}void CustomerArrived(Event en) {// 处理到达++CustomerNum;int durtime, innertime;
#ifdef DRandom(durtime, innertime); // 这样处理的好处是 更简单的随机sleep(3);
#elseP_B_Y("cin here ->   ")cin >> durtime >> innertime;
#endif// 下一个事件int NextCustomerTime = en.OccurTime + innertime;if(NextCustomerTime < CloseTime) EventOrderInsert(ev, {NextCustomerTime, 0}, cmp); //插入事件// 本事件加入到队列中int i = MinNum();q[i].push({en.OccurTime, durtime});//本事件离开时间加入到list中int LeftTime = en.OccurTime + durtime;if(q[i].size() == 1) EventOrderInsert(ev, {LeftTime, i}, cmp);
}void CustomerDeparture(Event en) {// 处理离开int i = en.NType;QEvent Customer = q[i].front();q[i].pop();TotalTime += (en.OccurTime - Customer.ArrivalTime);if (!q[i].empty()) {QEvent Customer = q[i].front();q[i].pop();EventOrderInsert(ev, {en.OccurTime + Customer.durtime, i}, cmp); // 将队列中一个预备离开的客户加入事件list}
}void EventListoutput() {P_W_R("list  (%d) :", (int)ev.size())P_B_R("\n  =======  [ head -> ")for (auto i : ev) {P_B_R("( %d, %d) -> ", i.OccurTime, i.NType)}P_B_R("end ]\n")
}void QEventoutput() {P_W_G("QEvent :   ");for (int i = 1; i <= 4; i++) {queue<QEvent> temp = q[i];P_B_G("\n  =======  QEvent %d :", i)P_B_Y("[");while (temp.size()) {QEvent tempQEvent = q[i].front();temp.pop();P_B_G("(%d, %d)", tempQEvent.ArrivalTime, tempQEvent.durtime)}P_B_Y("]");}
}void Bank_Simulation() {OpenForDay();while (!ev.empty()) {Event FirstEvent = ev.front();ev.pop_front(); // 取出第一个节点并且删除if (!FirstEvent.NType) CustomerArrived(FirstEvent);else CustomerDeparture(FirstEvent);EventListoutput();QEventoutput();cout << endl;}cout << "Average time is : " << (TotalTime / (CustomerNum)) << endl;
}int main() {Bank_Simulation();return 0;
}

https://github.com/lige1123/-


银行排队问题--事件链表+多窗口队列(数据结构课本)相关推荐

  1. 7-4 银行排队问题之单队列多窗口加VIP服务 (30 分)

    7-4 银行排队问题之单队列多窗口加VIP服务 (30 分) 说实话这道题挺恶心 有意思的,大模拟,主要的思路就是模拟时间轴. 题目描述 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时 ...

  2. 7-3 银行排队问题之单队列多窗口服务 (25 分)

    7-3 银行排队问题之单队列多窗口服务 (25 分) 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可 ...

  3. 7-46 银行排队问题之单队列多窗口服务 (10 分)

    7-46 银行排队问题之单队列多窗口服务 (10 分) 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口 ...

  4. 题353.2022暑期天梯赛训练-7-10 银行排队问题之单队列多窗口服务 (25 分)

    文章目录 题353.2022暑期天梯赛训练-7-10 银行排队问题之单队列多窗口服务 (25 分) 题目: 输入格式: 输出格式: 输入样例: 输出样例: **思路** **代码** 题353.202 ...

  5. 数据结构(二):线性表包括顺序存储结构(顺序表、顺序队列和顺序栈)和链式存储结构(链表、链队列和链栈)...

    还记得数据结构这个经典的分类图吧: 今天主要关注一下线性表. 什么是线性表 线性表的划分是从数据的逻辑结构上进行的.线性指的是在数据的逻辑结构上是线性的.即在数据元素的非空有限集中 (1) 存在唯一的 ...

  6. DSt:数据结构的简介、最强学习路线(逻辑结构【数组-链表-栈和队列/树-图-哈希】、物理结构、数据运算【十大排序/四大查找-图三大搜索-树三大遍历】、高级算法【贪心/分治/动态规划】之详细攻略

    DSt:数据结构的简介.最强学习路线(逻辑结构[数组-链表-栈和队列/树-图-哈希].物理结构[元素/关系].数据运算[十大排序/四大查找-图三大搜索-树三大遍历].高级算法[贪心/分治/动态规划]) ...

  7. 营业窗口队列模拟-2

    数据结构课程设计 海纳百川,大道致远 时光荏苒,青春在这里生长,为了理想我们在这里摩拳擦掌, 岁月不居,梦想依旧灿烂,纯真的理想在这里放飞 这个设计是为了让我们在队列的理解上更加的明白,然后自己做了一 ...

  8. 数据结构栈和队列_使您的列表更上一层楼:链接列表和队列数据结构

    数据结构栈和队列 When you want to store several elements somewhere in a program, the go-to data type is an a ...

  9. 一文带你认识队列数据结构

    摘要:对于队列来说数据结构相比栈复杂一些,但是也不是很难,搞懂先进先出然后用数组或者链表实现即可. 本文分享自华为云社区<手写各种队列,一文搞定>,原文作者:bigsai  . 前言 栈和 ...

最新文章

  1. AngularJS的使用方法
  2. VMware系列:将物理机热迁移到ESXi中(必藏喔)
  3. QT绘制散点图(1)
  4. C 库函数 - atoi()
  5. 在div中设置文字与内部div垂直居中
  6. CompletableFuture不能被打断
  7. java mybatis 教程_(整理)MyBatis入门教程(一)
  8. JS中数组和字符串具有的方法,以及substring,substr和slice的用法与区别
  9. 道路上下行是什么意思_了解道路禁止符号 春节压岁钱少填罚款
  10. C# list删除 另外list里面的元素_python学习笔记第三课:List(列表)
  11. SIP信令中的PRACK的含义和使用
  12. 史上最全计算机网络大纲
  13. android 9.0 安装xpose框架
  14. 应用虚拟化软件-VA虚拟应用管理平台
  15. Java给pdf添加页码(这是我之前的一篇文章)出现内存溢出Java heap space
  16. 手机突然显示无服务器,手机一直无服务是什么原因
  17. 【情报百科】如何使用FOCA进行OSINT文档元数据分析?
  18. 2022款联想拯救者R7000P和联想小新Pro16 选哪个好
  19. oracle dul 扫描磁盘,案例:Oracle dul数据挖掘 磁盘损坏dul提取数据文件中表的数据及l...
  20. gnu stubs arch linux,编译Nachos源代码时出现错误“gnu/stubs-32.h:No such file or directory”...

热门文章

  1. 2022年终总结, 2023 年度规划
  2. Markdown 语法汇总
  3. Linux中 ps -ef 指令详解
  4. 基于神经网络的目标检测论文之目标检测方法:改进的SSD目标检测算法
  5. 【Python】Tkinter开发笔记07:Sun-Valley-ttk-theme主题修改
  6. 百度地图实时路况数据-拥堵的生存分析
  7. 白话机器学习算法理论+实战之K近邻算法
  8. idea中文乱码设置
  9. 使用mybatis完成简单的crud操作
  10. 重力势能小车的设计方案