Airport Simulation 是数据结构与算法教材中用于演示Queue的一个小程序(大多数教师似乎会跳过这个练习)。主程序会通过输入总的运行时间、队列里可以等待的最多飞机数量,平均每个时间单元到来的飞机和离开的飞机(提供泊松分布的均值生成随机数)。

运行效果

程序的结构不算复杂,利用Runaway类来封装两个landing和takeoff队列,处理飞机的请求和行为;Plane类来封装飞机的状态和信息,以及在受到指令时输出信息到控制台。只是教材里的讲述有些分散,运行效果也由于输出太多而显得凌乱无比。练习布置许久之后也是一直没有找到一整块时间写完这个练习。这里是前几天完成的一个经过输出优化后的程序,格式比较易于观测。

该程序应在Linux或macOS下编译。在Windows下编译由于不支持彩色输出会出现一些奇怪的转移序列,sleep函数和usleep函数也应当用windows.h中提供的方法实现。

main.cpp和Random.h的源代码如下。其中Random.h用于提供泊松分布的随机数生成,参考自CSDN。

你可以在这里直接下载:https://billc.io/cloud/index.php/s/FeLekECBFKb6GkF

main.cpp:

#include <iostream>
#include <queue>
#include <unistd.h>
#include "Random.h"
using namespace std;
typedef int feedback;
const int success = 1;
const int fail = 0;
const int USPEED_SHORT = 1000;
const int USPEED_LONG = 1000;
enum flightStatus{null,toLand,toTakeoff
};
enum runawayAct{idle,letTakeoff,letLand
};
string percentage(int A, int B){char *temp = new char[100];sprintf(temp, "%3.2f%%", (double)A / (double)B * 100);string output = temp;return output;
}
class Plane{private:int ID;int comingTime;flightStatus status;public:Plane(){ID = -1;comingTime = -1;status = null;}Plane(int _ID, int _comingTime, flightStatus _status){usleep(USPEED_SHORT);ID = _ID;comingTime = _comingTime;status = _status;cout << "[PLANE MESSAGE] Plane NO." << ID << " is applying to " << ((status == toLand) ? "land " : "take off ") << endl;}feedback land(int currentTime){usleep(USPEED_LONG);cout << "\033[42m[PLANE MESSAGE] Plane NO." << ID << " has landed safely.\033[0m" << endl<< "                Waiting time before landing: " << currentTime - comingTime << "." << endl;}feedback takeoff(int currentTime){usleep(USPEED_LONG);cout << "\033[42m[PLANE MESSAGE] Plane NO." << ID << " has taken off.\033[0m" << endl<< "                Waiting time before taking off: " << currentTime - comingTime << "." << endl;}feedback reject(int currentTime){usleep(USPEED_LONG);if(status == toLand){cout << "\033[41m[AIRPORT MESSAGE] Plane NO." << ID << "'s landing request is rejected.\033[0m" << endl<< "                  It has been directed to other airports." << endl;}else{cout << "\033[41m[AIRPORT MESSAGE] Plane NO." << ID << " 's taking off request is rejected.\033[0m" << endl<< "                  This flight is delayed." << endl;}}int getTime(){return comingTime;}
};class Runaway{private:queue<Plane> landingQueue;queue<Plane> takeoffQueue;int limit;runawayAct act;int landingRequests;int landingAccepted;int landingRejected;int takeoffRequests;int takeoffAccepted;int takeoffRejected;int idleUnit;int landingWaitedTime;int takeoffWaitedTime;public:Runaway(int _limit){limit = _limit;landingRequests = 0;landingAccepted = 0;takeoffRequests = 0;takeoffAccepted = 0;takeoffRejected = 0;idleUnit = 0;landingWaitedTime = 0;takeoffWaitedTime = 0;}feedback CanLand(const Plane &current){landingRequests++;feedback result;if (landingQueue.size() < limit){result = success;landingQueue.push(current);}else{result = fail;landingRejected++;}return result;}feedback CanTakeoff(const Plane &current){takeoffRequests++;feedback result;if (takeoffQueue.size() < limit){result = success;takeoffQueue.push(current);}else{result = fail;takeoffRejected++;}return result;}runawayAct Act(int timeNow, Plane &moving){runawayAct result;if (!landingQueue.empty()){landingAccepted++;moving = landingQueue.front();landingWaitedTime += timeNow - moving.getTime();landingQueue.pop();return letLand;}else if(!takeoffQueue.empty()){takeoffAccepted++;moving = takeoffQueue.front();takeoffWaitedTime += timeNow - moving.getTime();takeoffQueue.pop();return letTakeoff;}else{idleUnit++;return idle;}}void SumUp(int simulationTime){cout << endl;cout << "\033[36m=============== SIMULATION RESULTS ===============\033[0m" << endl<< "\033[5;3mCalculating...\033[0m" << endl;sleep(2);cout<< "\033[1ATotal simulation time:                         " << simulationTime << endl<< "Total flights simulated:                       " << landingRequests + takeoffRequests << endl<< "Total flights required to land:                " << landingRequests << endl<< "Landing request accepted:                      " << landingAccepted << endl<< "Landing request rejected:                      " << landingRejected << endl<< "Total flights required to take off:            " << takeoffRequests << endl<< "Taking off request accepted:                   " << takeoffAccepted << endl<< "Taking off request rejected:                   " << takeoffRejected << endl<< "Flights still left in landing queue:           " << landingQueue.size() << endl<< "Flights still left in taking off queue:        " << takeoffQueue.size() << endl<< "Average waiting time in landing queue:         " << (float)landingWaitedTime / (float)landingAccepted << endl<< "Average waiting time in taking off queue:      " << (float)takeoffWaitedTime / (float)takeoffAccepted << endl<< "Average observing time for landing flights:    " << (float)landingRequests / (float)simulationTime << endl<< "Average observing time for taking off flights: " << (float)takeoffRequests / (float)simulationTime << endl<< "Ratio for successfully landed flights:         " << percentage(landingAccepted, landingRequests) << endl<< "Ratio for successfully took off flights:       " << percentage(landingAccepted, landingRequests) << endl<< "Ratio of runaway idle time:                    " << percentage(idleUnit, simulationTime) << endl<< endl<< "\033[3;2mSimulation finished.\033[0m" << endl;}
};
void initilize(int &totalTime, int &queueLimit, float &arrivingRate, float &departureRate){cout << "\033[2J\033[0;0H";cout << "Welcome to the \033[46mAIRPORT SIMULATOR\033[0m." << endl;sleep(1);cout << "\033[36mPlease enter how many time units you will simulate:\033[0m\n"<< flush;cin >> totalTime;cout << "\033[36mHow many flights can be waiting to land or takeoff?\033[0m" << endl<< flush;cin >> queueLimit;cout << "\033[36mWhat is the expected arriving flights per unit time?\033[0m" << endl<< flush;cin >> arrivingRate;cout << "\033[36mWhat is the expected departing flights per unit time?\033[0m" << endl<< flush;cin >> departureRate;
}int main(){
START:float arrivingRate, departureRate;int totalTime, queueLimit;initilize(totalTime, queueLimit, arrivingRate, departureRate);int currentTime;int planeID = 0;Random randomSeed;Runaway airport(queueLimit);for (currentTime = 0; currentTime < totalTime; currentTime++){cout << "\033[2m----- Current excution time: " << currentTime << " -----\033[0m" << endl;int comingPerUnit = randomSeed.poisson(arrivingRate);for (int num = 0; num < comingPerUnit; num++, planeID++){Plane currentPlane(planeID, currentTime, toLand);if(airport.CanLand(currentPlane)==fail){currentPlane.reject(currentTime);}}int departingPerUnit = randomSeed.poisson(departureRate);for (int num = 0; num < departingPerUnit; num++, planeID++){Plane currentPlane(planeID, currentTime, toTakeoff);if(airport.CanTakeoff(currentPlane)==fail){currentPlane.reject(currentTime);}}Plane movingPlane;switch (airport.Act(currentTime, movingPlane)){case letLand:movingPlane.land(currentTime);break;case letTakeoff:movingPlane.takeoff(currentTime);break;case idle:cout << "\033[46m[AIRPORT MESSAGE]: Runaway is idle.\033[0m" << endl;break;}}airport.SumUp(totalTime);char ch;cout << "\033[36mDo you want to initialize another simulation? \n([R] or [r] to restart, any other key to exit.)\033[0m" << endl;while(cin.get()!='\n');if (toupper(ch = cin.get()) == 'R')goto START;return 0;
}

Random.h:

#ifndef RANDOM_H_INCLUDED
#define RANDOM_H_INCLUDED#include <iostream>
#include <time.h>
#include <limits.h>
#include <math.h>using namespace std;class Random
{public:Random(bool pseudo = true);double random_real();int random_integer(int low, int high);int poisson(double mean);private:int reseed();                 //  Re-randomize the seed.int seed, multiplier, add_on; //  constants for use in arithmetic operations
};
#include "Random.h"Random::Random(bool pseudo)
/*Post: The values of seed, add_on, and multiplier areinitialized.  The seed is initialized randomly only if pseudo == false.
*/
{if (pseudo)seed = 1;elseseed = time(NULL) % INT_MAX;multiplier = 2743; // 斜率add_on = 5923;     // 位移
}int Random::reseed()
//Post: The seed is replaced by a pseudorandom successor.
{seed = seed * multiplier + add_on;return seed;
}double Random::random_real()
/*Post: A random real number between 0 and 1 is returned.*/
{double max = INT_MAX + 1.0; //INT_MAX = (2)31 -1double temp = reseed();if (temp < 0)temp = temp + max;return temp / max;
}int Random::random_integer(int low, int high) // 这个函数在泊松分布中没有用到
{double max = INT_MAX + 1.0; //INT_MAX = (2)31 -1double temp = reseed();if (temp < 0)temp = temp + max;return (int)(temp / (max / (high - low + 1.0) + low)); // 返回整数,且有规定范围
}int Random::poisson(double mean) // 泊松分布的实现
{double x = -1;double u;double log1, log2;log1 = 0;log2 = -mean;do{u = random_real();log1 += log(u);x++;} while (log1 >= log2);return x;
}
#endif // RANDOM_H_INCLUDED

来源:https://billc.io/2019/03/airport-simulation/

转载于:https://www.cnblogs.com/BillChen2000/p/airport-simulation.html

Airport Simulation (数据结构与算法 – 队列 / Queue 的应用)相关推荐

  1. 数据结构与算法---队列

    数据结构与算法-队列 1. 队列的定义: 队列(Queue )简称队,是一种操作受限制 的线性表 ,只允许在表的一端进行插入,而在表的另一端进行删除.向队列中插入元素称为入队或进队: 删除元素称为出队 ...

  2. JavaScript数据结构与算法——队列详解(下)

    接下来会借助本人另一篇文章JavaScript数据结构与算法--队列详解(上)中实现的队列类及其方法实现一个应用. 配对问题 需求分析:在一个文件中保存着一份男女混合的数据,名称前以B开头表示男士,以 ...

  3. javascript数据结构与算法---队列

    javascript数据结构与算法---队列 队列是一种列表,不同的是队列只能在队尾插入元素,在队首删除元素.队列用于存储按顺序排列的数据,先进先出,这点和栈不一样(后入先出).在栈中,最后入栈的元素 ...

  4. JavaScript数据结构与算法——队列详解(上)

    队列基本知识 队列是一种与列表很像的数据结构,只是队列只能在尾部插入元素,在队首删除元素.队列用于存放按顺序排列的元素,先进先出,就像食堂排队一样,后来的只能排在后面,先来的先拿饭,一种井然有序的感觉 ...

  5. c++数据结构中 顺序队列的队首队尾_数据结构与算法—队列详解

    前言 栈和队列是一对好兄弟,前面我们介绍过数据结构与算法-栈详解,那么栈的机制相对简单,后入先出,就像进入一个狭小的山洞,山洞只有一个出口,只能后进先出(在外面的先出去).而队列就好比是一个隧道,后面 ...

  6. c++数据结构中 顺序队列的队首队尾_数据结构与算法—队列图文详解

    前言 栈和队列是一对好兄弟,前面我们介绍过数据结构与算法-栈详解,那么栈的机制相对简单,后入先出,就像进入一个狭小的山洞,山洞只有一个出口,只能后进先出(在外面的先出去).而队列就好比是一个隧道,后面 ...

  7. 数据结构与算法 / 队列(queue)

    @time 2019-08-04 @author Ruo_Xiao 一.定义 队列是一种操作受限的线性表,只能从一端插入从另一端弹出的数据结构. 二.特性 先进者先出,后进者后出. 三.分类 1.基于 ...

  8. 数据结构与算法 | 队列

    队列 队列只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特性,就如同我们排队一样,先排的就先出去. 而进行插入的一端叫做队尾,进行删除的一端叫做队头 队列可以用 ...

  9. (三)数据结构与算法-队列

    银行排队案例 队列介绍 队列是一个有序列表,可以用数组或是链表来实现 遵循先入先出原则.即:先存入队列的数据,要先取出.后存入的要后取出 数组模拟队列 队列本身是有序表,若使用数组的结构来存储队列的数 ...

最新文章

  1. 高质量的友谊总是发生在两个优秀的独立人格之间
  2. 前端开发的浏览器知识
  3. 我是怎么把一个项目带崩的
  4. Vagrant 构建 Linux 开发环境
  5. JS面向对象的程序设计
  6. mac 下设置 sublime text2 的命令行快捷方式 subl
  7. plsql 破解|oracle plsql 破解
  8. OneNote笔记备份
  9. 训练模型两种保存方式 saver& load
  10. 组织结构图的画法——office的应用
  11. 极客日报:字节跳动辟谣“出售AI技术”和“成立打车项目”;GitHub 因代码版权问题遭抵制;贝佐斯正式卸任亚马逊 CEO
  12. 关于Android高德地图路线规划的学习
  13. CSS之BFC、IFC、GFC、FFC简述
  14. k8s(一)、 1.9.0高可用集群本地离线部署记录
  15. 7-53 生化危机——dfs
  16. php 传递指针,windtear 追求完美
  17. Portraiture中文版最新mac3.5版win5.0版插件介绍
  18. Java位运算总结:位运算用途广泛
  19. 计算机 网络安全 研究生专业大学排名,2020年最好的网络空间安全专业大学排名...
  20. html 标签使内容在一行,css如何使文字在一行上?

热门文章

  1. html5+ 原生标题栏添加input 输入框
  2. 一张具有纪念意义的图片,图中的程序员你认识么?他近况如何?
  3. Centos 安装docker后 deamo 无法启动的问题 解决
  4. Java web Servlet弹出提示框方法
  5. 【数据分析】什么是数据分析? 分析和管理数据以做出决策
  6. kernel编译练习2:给ubuntu22升级5.19内核
  7. 线性代数笔记21——伴随矩阵和克莱姆法则
  8. 机器学习之分类器性能指标之ROC曲线、AUC值
  9. 大型电商架构亿级流量电商详情页系统--实战 服务降级
  10. 新闻发布系统之分页查询and评论