银行排队问题--事件链表+多窗口队列(数据结构课本)
银行排队问题
事件驱动模拟问题
问题分析:
银行开放了4个窗口,现在客户要从四面八方到银行办理业务;根据常识,到银行就少不了排队。我们排队按最短队伍排列,中途不切换队伍。
现在随机生成到银行办理业务的人之间的 时间差 i n n n e r t i m e innnertime innnertime ,和办理业务所需的时间 d u r t i m e durtime durtime。完成事件链的模拟和三个队列的模拟,并计算每个人在银行的 平均逗留时间。
注意:
逗留事件不等于办理业务的时间,等于排队时间 + 办理业务时间;
事件有序链表
按照 OccurTime 顺序排列;
四个队列结构图
队列里是客户,事件列表里是客户的两个时间(到达/离开)。
数据处理:
对于时间类型分成四种:
EType 事件类型 0 到达银行 N > 0 由 n n n 号窗口离开 队列链表数据结构处理如图所示。
处理流程:
蓝色 计算平均逗留时间;
红色 、绿色 代表不同的客户;
初始化银行里新的一天~
定义事件链表、窗口队列数组、累计客户逗留时间、累计客户数;
为了方便处理,在事件链表中加入一个 0 时间的客户到达操作;
取出事件队列里的事件,处理不同的事件类型;
处理到达 客户到达事件
首先,用户数量增加1
取到随机数(题目处理的随机数是有原因的)DurTime innerTime 业务处理和间隔时间
本次随机数的 客户的到达事件,也就是本客户到达事件之后的客户加入 到事件链表中;
选择长度最小的队列,本次 客户 加入到队列中;
如果队列中有且仅有 1 个 客户,那么我们把这个 客户的离开事件加入到事件列表里;在队列里删除;
为什么
如果这个队列大于1,那么说明前面有更多的客户离开事件需要处理,
按流程来说,我们的客户也是不需要离开的。
只有这个队列是 1 个人的时候,我们才可以用已知的 客户到达事件 发生时间 计算客户离开发生时间。 (到达时间 + 事务处理时间即可)。
处理 客户离开事件离开事件
- 首先选择出正确的 队列,取出队列首元素并删除;
- 用户总时间,离开时间减去到达时间;
- 判断此队列中是否有 需要离开的客户; 队列不为空,取出队列首元素,把该事件加入到事件列表中;离开事件发生时间是 此事件发生时间 + 客户的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/-
银行排队问题--事件链表+多窗口队列(数据结构课本)相关推荐
- 7-4 银行排队问题之单队列多窗口加VIP服务 (30 分)
7-4 银行排队问题之单队列多窗口加VIP服务 (30 分) 说实话这道题挺恶心 有意思的,大模拟,主要的思路就是模拟时间轴. 题目描述 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时 ...
- 7-3 银行排队问题之单队列多窗口服务 (25 分)
7-3 银行排队问题之单队列多窗口服务 (25 分) 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可 ...
- 7-46 银行排队问题之单队列多窗口服务 (10 分)
7-46 银行排队问题之单队列多窗口服务 (10 分) 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口 ...
- 题353.2022暑期天梯赛训练-7-10 银行排队问题之单队列多窗口服务 (25 分)
文章目录 题353.2022暑期天梯赛训练-7-10 银行排队问题之单队列多窗口服务 (25 分) 题目: 输入格式: 输出格式: 输入样例: 输出样例: **思路** **代码** 题353.202 ...
- 数据结构(二):线性表包括顺序存储结构(顺序表、顺序队列和顺序栈)和链式存储结构(链表、链队列和链栈)...
还记得数据结构这个经典的分类图吧: 今天主要关注一下线性表. 什么是线性表 线性表的划分是从数据的逻辑结构上进行的.线性指的是在数据的逻辑结构上是线性的.即在数据元素的非空有限集中 (1) 存在唯一的 ...
- DSt:数据结构的简介、最强学习路线(逻辑结构【数组-链表-栈和队列/树-图-哈希】、物理结构、数据运算【十大排序/四大查找-图三大搜索-树三大遍历】、高级算法【贪心/分治/动态规划】之详细攻略
DSt:数据结构的简介.最强学习路线(逻辑结构[数组-链表-栈和队列/树-图-哈希].物理结构[元素/关系].数据运算[十大排序/四大查找-图三大搜索-树三大遍历].高级算法[贪心/分治/动态规划]) ...
- 营业窗口队列模拟-2
数据结构课程设计 海纳百川,大道致远 时光荏苒,青春在这里生长,为了理想我们在这里摩拳擦掌, 岁月不居,梦想依旧灿烂,纯真的理想在这里放飞 这个设计是为了让我们在队列的理解上更加的明白,然后自己做了一 ...
- 数据结构栈和队列_使您的列表更上一层楼:链接列表和队列数据结构
数据结构栈和队列 When you want to store several elements somewhere in a program, the go-to data type is an a ...
- 一文带你认识队列数据结构
摘要:对于队列来说数据结构相比栈复杂一些,但是也不是很难,搞懂先进先出然后用数组或者链表实现即可. 本文分享自华为云社区<手写各种队列,一文搞定>,原文作者:bigsai . 前言 栈和 ...
最新文章
- AngularJS的使用方法
- VMware系列:将物理机热迁移到ESXi中(必藏喔)
- QT绘制散点图(1)
- C 库函数 - atoi()
- 在div中设置文字与内部div垂直居中
- CompletableFuture不能被打断
- java mybatis 教程_(整理)MyBatis入门教程(一)
- JS中数组和字符串具有的方法,以及substring,substr和slice的用法与区别
- 道路上下行是什么意思_了解道路禁止符号 春节压岁钱少填罚款
- C# list删除 另外list里面的元素_python学习笔记第三课:List(列表)
- SIP信令中的PRACK的含义和使用
- 史上最全计算机网络大纲
- android 9.0 安装xpose框架
- 应用虚拟化软件-VA虚拟应用管理平台
- Java给pdf添加页码(这是我之前的一篇文章)出现内存溢出Java heap space
- 手机突然显示无服务器,手机一直无服务是什么原因
- 【情报百科】如何使用FOCA进行OSINT文档元数据分析?
- 2022款联想拯救者R7000P和联想小新Pro16 选哪个好
- oracle dul 扫描磁盘,案例:Oracle dul数据挖掘 磁盘损坏dul提取数据文件中表的数据及l...
- gnu stubs arch linux,编译Nachos源代码时出现错误“gnu/stubs-32.h:No such file or directory”...