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 = ;
const int fail = ;
const int USPEED_SHORT = ;
const int USPEED_LONG = ;
enum flightStatus{
null,
toLand,
toTakeoff
};
enum runawayAct{
idle,
letTakeoff,
letLand
};
string percentage(int A, int B){
char *temp = new char[];
sprintf(temp, "%3.2f%%", (double)A / (double)B * );
string output = temp;
return output;
}
class Plane{
private:
int ID;
int comingTime;
flightStatus status;
public:
Plane(){
ID = -;
comingTime = -;
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 = ;
landingAccepted = ;
takeoffRequests = ;
takeoffAccepted = ;
takeoffRejected = ;
idleUnit = ;
landingWaitedTime = ;
takeoffWaitedTime = ;
}
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();
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();
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 = ;
Random randomSeed;
Runaway airport(queueLimit);
for (currentTime = ; currentTime < totalTime; currentTime++){
cout << "\033[2m----- Current excution time: " << currentTime << " -----\033[0m" << endl;
int comingPerUnit = randomSeed.poisson(arrivingRate);
for (int num = ; 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 = ; 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 ;
}

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 are
initialized. The seed is initialized randomly only if pseudo == false.
*/
{
if (pseudo)
seed = ;
else
seed = time(NULL) % INT_MAX;
multiplier = ; // 斜率
add_on = ; // 位移
} 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 -1
double temp = reseed();
if (temp < )
temp = temp + max;
return temp / max;
} int Random::random_integer(int low, int high) // 这个函数在泊松分布中没有用到
{
double max = INT_MAX + 1.0; //INT_MAX = (2)31 -1
double temp = reseed();
if (temp < )
temp = temp + max;
return (int)(temp / (max / (high - low + 1.0) + low)); // 返回整数,且有规定范围
} int Random::poisson(double mean) // 泊松分布的实现
{
double x = -;
double u;
double log1, log2;
log1 = ;
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/

Airport Simulation (数据结构与算法 – 队列 / Queue 的应用)的更多相关文章

  1. [数据结构与算法]队列Queue 的多种实现

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

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

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

  3. JavaScript数据结构与算法-队列练习

    队列的实现 // 队列类 function Deque () { this.dataStore = []; this.enqueueFront = enqueueFront; this.enqueue ...

  4. python数据结构与算法——队列

    队列结构可以使用数组来模拟,只需要设定头和尾的两个标记 参考自<啊哈> # 按书中的代码会出现索引越界的问题(书中申请了超量的空间) # 尝试令tai初始为len(q)-1则不会出错但少了 ...

  5. 每周一练 之 数据结构与算法(Queue)

    这是第二周的练习题,这里补充下咯,五一节马上就要到了,自己的计划先安排上了,开发一个有趣的玩意儿. 下面是之前分享的链接: 1.每周一练 之 数据结构与算法(Stack) 2.每周一练 之 数据结构与 ...

  6. C语言- 基础数据结构和算法 - 队列的顺序存储

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  7. JS数据结构与算法-队列结构

    队列结构 一.认识队列 受限的线性结构: 我们已经学习了一种受限的线性结构:栈结构. 并且已经知道这种受限的数据结构对于解决某些特定问题,会有特别的 效果. 下面,我们再来学习另外一个受限的数据结构: ...

  8. JavaScript数据结构和算法----队列

    前言 队列和栈很像,只是用了不同的原则.队列是遵循先进先出(FIFO)原则的一组有序的的项,队列在尾部添加新元素,从顶部移除元素.最新添加的元素必须必须排队在队列的,末尾.可以想象食堂排队买饭的样子. ...

  9. js数据结构与算法——队列

    <script> //创建一个队列 function Queue(){ let items = []; //向队尾添加一个新的项 this.enqueue = function(eleme ...

随机推荐

  1. JAVA的堆栈和内存、垃圾回收解说

    1.有关java健壮性特点的真相 很多书上都说java健壮性的特点是因为java使用数组代替了c++的指针:c++最令人头痛的问题就是内存问题,java的健壮性使编程人员不用再考虑内存的问题:这种观点 ...

  2. R的基础数据结构

  3. python标准库:datetime模块

    原文地址:http://www.bugingcode.com/blog/python_datetime.html datatime 模块题共用一些处理日期,时间和时间间隔的函数.这个模块使用面向对象的 ...

  4. Protocol Buffers学习(4):更多消息类型

    介绍一下消息的不同类型和引用 使用复杂消息类型 您可以使用其他消息类型作为字段类型.例如,假设你想在每个SearchResponse消息中包含Result消息,您可以在同一个.proto中定义一个Re ...

  5. 用Gitolite搭建服务器上的Git

    使用git作为版本控制工具,确实非常流行且好用,常用的git代码服务器有Github还是国内的Gitcafe和OSC都是很不错,可以免费存放一些开源的项目代码,对于私人项目,则需要支付一定的费用.同时 ...

  6. MySQL安装和常用命令

    一.安装MySQL groupadd mysqluseradd -r -g mysql mysqlgroups mysqlfind / -name mysql | xargs rm -rfwget h ...

  7. Book. Effective C++ item2-尽量使用const, enum, inline替换#define

    ##常规变量 c++里面的#define后面的定义部分,是不算代码的一部分的.所以如果你使用#define: #define ASPECT_RATIO 1.653 你希望这个代号ASPECT RATI ...

  8. Java GUI记账本(基于Mysql&&文件存储两种版本)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.java * 作者:常轩 * 微信公众号:Worldh ...

  9. Spark ML机器学习库评估指标示例

    本文主要对 Spark ML库下模型评估指标的讲解,以下代码均以Jupyter Notebook进行讲解,Spark版本为2.4.5.模型评估指标位于包org.apache.spark.ml.eval ...

  10. cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'mvc:resources'.

    新的错误出现  spring-mvc.xml文件 <mvc:resources mapping="/static/**" location="/static/&qu ...