|
|
|
|
# P5:机场起降模拟系统
|
|
|
|
|
|
|
|
|
|
马誉航、王振宇、王意伟、宋岱瑾
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**摘要**:随着航空运输和长途旅游业的迅速发展,飞机的需求量在日常生活中逐渐增多,机场航班的起降协调工作也变得越来越重要。而随着时代发展,充满着主观性,不确定性的传统塔楼式人工调度已经无法满足机场的现代化需求,并且在机场规模逐渐增大,飞机班次逐渐增多的今天,使用传统的调度方式也容易出现调度冲突和信息延误等问题。针对这些问题,我们设计了这个模拟机场调度的代码,有效模拟了单位时间内飞机起降的各类数据。同时,为了进一步提高模拟数据的真实性,我们通过生成随机数,使用泊松分布等方法使得模拟结果更具有参考价值。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
任务分工及完成情况。
|
|
|
|
|
| 任务 | 人员 |
|
|
|
|
|
|---|---|
|
|
|
|
|
| 文档资料查询 | 马誉航 、王意伟 |
|
|
|
|
|
| 文档汇总 | 王振宇、马誉航 |
|
|
|
|
|
| 代码资料查询 | 王振宇、宋岱瑾、王意伟 |
|
|
|
|
|
| 代码开发 | 宋岱瑾、王振宇、马誉航、王意伟 |
|
|
|
|
|
| 代码测试 | 王意伟、宋岱瑾 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
工作量占比。
|
|
|
|
|
```
|
|
|
|
|
宋岱瑾 王振宇 王意伟 马誉航
|
|
|
|
|
25 25 25 25
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 1. 系统分析
|
|
|
|
|
|
|
|
|
|
## 1.1 问题描述
|
|
|
|
|
|
|
|
|
|
考虑一个繁忙的小型机场仅有一个跑道。在每个单位时间内,只有一架飞机可以降落或起飞,但不能同时进行。随时有飞机准备着降落或起飞,因此在任何给定的时刻,跑道可能是空闲的,或者一架飞机正在降落或起飞,也可能有几架飞机等待着降落或起飞。在模拟中,我们特别关注飞机在起飞或降落时需要排队等待的时间,因此,测量时间对我们的程序至关重要。我们将模拟时间划分为单位,使得在任何给定的时间单位内,只有一架飞机可以利用跑道进行起飞或降落。
|
|
|
|
|
|
|
|
|
|
(1)模拟开始前,用户应设定模拟时长,等待起飞或降落的队列最大容量,单位时间内到达的飞机数量期望值,单位时间内离开的飞机数量期望值。
|
|
|
|
|
(2)每一个时间单位内,随机生成准备起飞或降落的飞机,并进入等待队列;若等待降落队列已满,则拒绝降落,引导到其他机场降落;若等待起飞队列已满,则拒绝起飞,安排其他时间起飞。
|
|
|
|
|
(3)若有飞机等待降落,则优先处理飞机降落,若没有飞机等待降落,才允许等待的飞机起飞;既没有飞机降落,也没有飞机起飞时,跑道空闲。
|
|
|
|
|
(4)模拟结束后,给出统计数据,至少包括处理的飞机总数,请求降落的飞机数,请求起飞的飞机数,接受降落的飞机数,接受起飞的飞机数,拒绝降落的飞机数,拒绝起飞的飞机数,实际降落的飞机数,实际起飞的飞机数,仍在等待降落的飞机数,仍在等待起飞的飞机数,跑道空闲时间占比,平均等待降落时间,平均等待起飞时间。要求系统运行正常、功能完整;数据结构使用得当,算法有较高的效率;代码
|
|
|
|
|
规范、可读性高,结构清晰;具备一定的健壮性、可靠性和可维护性。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 1.2 可行性分析
|
|
|
|
|
|
|
|
|
|
机场只有一个跑道,准备降落的飞机和准备起飞的飞机分别组成一个队列,排队等待降落和起飞。本项目涉及的对象主要包括飞机、跑道,等待降落和起飞的队列。假设每个单位时间内,平均起飞(降落)的飞机数为 ,则下一个单位时间内起飞(降落)的飞机数服从参数为 的泊松分布(Poisson distribution)
|
|
|
|
|
|
|
|
|
|
## 1.3 需求分析
|
|
|
|
|
|
|
|
|
|
### (1)输入和输出
|
|
|
|
|
|
|
|
|
|
用户首先输入自主设定的数据,如飞机场运行时间,起飞和降落队列最多容纳的飞机数目,和单位时间内请求起飞和降落的飞机的频数,为程序设定计算的条件和初始值。程序在经过运行后输出根据输入数据所得的,本次运行的统计数据和具体情况,分析各类不同情况下的飞机的数目,跑道空闲时间占比,平均落地时间等用户所需求数据。
|
|
|
|
|
|
|
|
|
|
### (2)参数设定
|
|
|
|
|
|
|
|
|
|
1.飞机运行的时间。
|
|
|
|
|
2.降落和起飞队列最多容纳的飞机数。
|
|
|
|
|
3.平均每个单位时间请求降落的飞机数。
|
|
|
|
|
4.平均每个单位时间请求起飞的飞机数。
|
|
|
|
|
|
|
|
|
|
### (3)生成随机数功能
|
|
|
|
|
|
|
|
|
|
rand()会返回一随机数值, 范围在0至RAND_MAX 间。RAND_MAX定义在stdlib.h, 其值为2147483647。
|
|
|
|
|
```
|
|
|
|
|
———————————————————————————
|
|
|
|
|
| # include <iostream> |
|
|
|
|
|
| |
|
|
|
|
|
| using namespace std; |
|
|
|
|
|
| int main() |
|
|
|
|
|
| { |
|
|
|
|
|
| for(int i=0;i<10;i++) |
|
|
|
|
|
| { |
|
|
|
|
|
| cout<<rand()<<endl; |
|
|
|
|
|
| } |
|
|
|
|
|
|} |
|
|
|
|
|
————————————————————————————
|
|
|
|
|
```
|
|
|
|
|
### (4)泊松分布功能
|
|
|
|
|
|
|
|
|
|
```c++
|
|
|
|
|
int Random::poisson(double mean)
|
|
|
|
|
{
|
|
|
|
|
double limit=exp(-mean);
|
|
|
|
|
double product=random_real();
|
|
|
|
|
int count=0;
|
|
|
|
|
while(product>limit){
|
|
|
|
|
count++;
|
|
|
|
|
product*=random_real();
|
|
|
|
|
}
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 系统设计
|
|
|
|
|
|
|
|
|
|
## 2.1 概要设计
|
|
|
|
|
|
|
|
|
|
模块一:随机数的生成以及泊松分布的实现;
|
|
|
|
|
模块二:将起飞和降落的飞机分为两个队列并且分别处理请求;
|
|
|
|
|
模块三:使用printf函数输出过程。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 2.2 数据结构设计
|
|
|
|
|
|
|
|
|
|
以下是用到的数据结构:
|
|
|
|
|
|
|
|
|
|
飞机:设计一个结构体或类来表示飞机,包括飞机的编号、起降状态、起飞时间、降落时间、所属航班等信息。
|
|
|
|
|
|
|
|
|
|
航线:设计一个结构体或类来表示航线,包括航班编号、起降机场、航班状态、预计起飞时间、预计降落时间等信息。
|
|
|
|
|
|
|
|
|
|
排队队列:设计一个队列结构来存储飞机的起飞或降落排队队列信息。
|
|
|
|
|
|
|
|
|
|
栈:用来存储已经起飞或降落的飞机信息,方便回退操作。
|
|
|
|
|
|
|
|
|
|
###(1)queue队列结构
|
|
|
|
|
设计一个队列结构来存储飞机的起飞或降落排队队列信息。
|
|
|
|
|
```
|
|
|
|
|
queue <struct plane> q1; //q1是准备降落的飞机队列
|
|
|
|
|
queue <struct plane> q2; //q2是准备起飞的飞机队列
|
|
|
|
|
```
|
|
|
|
|
###(2)Random结构
|
|
|
|
|
生成随机数:
|
|
|
|
|
```
|
|
|
|
|
class Random{
|
|
|
|
|
public:
|
|
|
|
|
Random(bool pseudo=true);
|
|
|
|
|
double random_real();
|
|
|
|
|
int poisson(double mean);
|
|
|
|
|
private:
|
|
|
|
|
int reseed();
|
|
|
|
|
int seed,
|
|
|
|
|
multiplier,add_on;
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
###(3)plane结构
|
|
|
|
|
```
|
|
|
|
|
struct plane{
|
|
|
|
|
int name;
|
|
|
|
|
int in_queue_time;
|
|
|
|
|
} plane;
|
|
|
|
|
```
|
|
|
|
|
## 2.3 算法设计
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### (1)泊松分布实现随机数生成算法
|
|
|
|
|
```
|
|
|
|
|
class Random{
|
|
|
|
|
public:
|
|
|
|
|
Random(bool pseudo=true);
|
|
|
|
|
double random_real();
|
|
|
|
|
int poisson(double mean);
|
|
|
|
|
private:
|
|
|
|
|
int reseed();
|
|
|
|
|
int seed,
|
|
|
|
|
multiplier,add_on;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int Random::reseed()
|
|
|
|
|
{
|
|
|
|
|
seed=seed*multiplier + add_on;
|
|
|
|
|
return seed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Random::Random(bool pseudo)
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
if(pseudo)
|
|
|
|
|
seed=1;
|
|
|
|
|
else
|
|
|
|
|
seed=time(NULL)%INT_MAX;
|
|
|
|
|
multiplier=2743;
|
|
|
|
|
add_on=5923;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double Random::random_real()
|
|
|
|
|
{
|
|
|
|
|
double max=INT_MAX + 1.0;
|
|
|
|
|
double temp=reseed();
|
|
|
|
|
if(temp<0)
|
|
|
|
|
temp=temp+max;
|
|
|
|
|
return temp/max;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Random::poisson(double mean)
|
|
|
|
|
{
|
|
|
|
|
double limit=exp(-mean);
|
|
|
|
|
double product=random_real();
|
|
|
|
|
int count=0;
|
|
|
|
|
while(product>limit){
|
|
|
|
|
count++;
|
|
|
|
|
product*=random_real();
|
|
|
|
|
}
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
### (2)排队算法
|
|
|
|
|
```
|
|
|
|
|
if(!q1.empty()){
|
|
|
|
|
temp=q1.front();
|
|
|
|
|
wait_time=i-temp.in_queue_time-1;
|
|
|
|
|
come_wait_time+=wait_time;
|
|
|
|
|
printf("\n\n##%d号时间##\n%d号飞机降落了,等了%d个单位时间。\n", i, temp.name , wait_time);
|
|
|
|
|
q1.pop();
|
|
|
|
|
}
|
|
|
|
|
else if(!q2.empty()){
|
|
|
|
|
temp=q2.front();
|
|
|
|
|
wait_time=i-temp.in_queue_time-1;
|
|
|
|
|
go_wait_time+=wait_time;
|
|
|
|
|
printf("\n\n##%d号时间##\n%d号飞机飞走了,等了%d个单位时间。\n", i, temp.name , wait_time);
|
|
|
|
|
q2.pop();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
printf("\n\n##%d号时间##\n没有飞机降落,也没有飞机起飞,此时跑道为空。\n",i);
|
|
|
|
|
spare_time++;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 3. 系统实现
|
|
|
|
|
#####系统使用C++语言进行开发,使用VScode作为开发工具。
|
|
|
|
|
#####项目的文件结构如下:
|
|
|
|
|
c.cpp:主程序文件,包含程序的主函数和主要逻辑。
|
|
|
|
|
README.md:项目文档,包含程序的介绍和使用说明。
|
|
|
|
|
|
|
|
|
|
#####程序的主要函数包括:
|
|
|
|
|
Random():构造函数,初始化随机数生成器。
|
|
|
|
|
random_real():生成0~1之间的随机实数。
|
|
|
|
|
poisson():生成泊松分布的随机数。
|
|
|
|
|
main():主函数,包含程序的主要逻辑,如输入、处理、输出等。包括两个队列的入队和出队,以及每个飞机的等待时间计算和输出。
|
|
|
|
|
## 3.1 核心数据结构的实现
|
|
|
|
|
|
|
|
|
|
在程序中,定义了两个queue对象,一个用于存储准备降落的飞机,另一个则用于存储准备起飞的飞机。每个队列中存储结构体类型的plane对象,表示每个飞机的编号和进入队列的时间。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 3.2 核心算法的实现
|
|
|
|
|
系统的核心算法主要包括泊松分布实现随机数生成算法和排队算法
|
|
|
|
|
|
|
|
|
|
# 4. 系统测试
|
|
|
|
|
```
|
|
|
|
|
——————————————————————————————————————————————
|
|
|
|
|
请输入飞机场运行的时间。
|
|
|
|
|
20
|
|
|
|
|
请输入降落和起飞队列最多容纳的飞机数。
|
|
|
|
|
5
|
|
|
|
|
请输入平均每个单位时间请求降落的飞机数。
|
|
|
|
|
0.4
|
|
|
|
|
请输入平均每个单位时间请求起飞的飞机数。
|
|
|
|
|
0.5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##0号时间##
|
|
|
|
|
没有飞机降落,也没有飞机起飞,此时跑道为空。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##1号时间##
|
|
|
|
|
没有飞机降落,也没有飞机起飞,此时跑道为空。
|
|
|
|
|
0号飞机请求起飞,并进入起飞队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##2号时间##
|
|
|
|
|
0号飞机飞走了,等了0个单位时间。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##3号时间##
|
|
|
|
|
没有飞机降落,也没有飞机起飞,此时跑道为空。
|
|
|
|
|
1号飞机请求降落,并进入降落队伍。
|
|
|
|
|
2号飞机请求起飞,并进入起飞队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##4号时间##
|
|
|
|
|
1号飞机降落了,等了0个单位时间。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##5号时间##
|
|
|
|
|
2号飞机飞走了,等了1个单位时间。
|
|
|
|
|
3号飞机请求起飞,并进入起飞队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##6号时间##
|
|
|
|
|
3号飞机飞走了,等了0个单位时间。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##7号时间##
|
|
|
|
|
没有飞机降落,也没有飞机起飞,此时跑道为空。
|
|
|
|
|
4号飞机请求起飞,并进入起飞队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##8号时间##
|
|
|
|
|
4号飞机飞走了,等了0个单位时间。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##9号时间##
|
|
|
|
|
没有飞机降落,也没有飞机起飞,此时跑道为空。
|
|
|
|
|
5号飞机请求起飞,并进入起飞队伍。
|
|
|
|
|
6号飞机请求起飞,并进入起飞队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##10号时间##
|
|
|
|
|
5号飞机飞走了,等了0个单位时间。
|
|
|
|
|
7号飞机请求起飞,并进入起飞队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##11号时间##
|
|
|
|
|
6号飞机飞走了,等了1个单位时间。
|
|
|
|
|
8号飞机请求起飞,并进入起飞队伍。
|
|
|
|
|
9号飞机请求起飞,并进入起飞队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##12号时间##
|
|
|
|
|
7号飞机飞走了,等了1个单位时间。
|
|
|
|
|
10号飞机请求降落,并进入降落队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##13号时间##
|
|
|
|
|
10号飞机降落了,等了0个单位时间。
|
|
|
|
|
11号飞机请求起飞,并进入起飞队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##14号时间##
|
|
|
|
|
8号飞机飞走了,等了2个单位时间。
|
|
|
|
|
12号飞机请求降落,并进入降落队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##15号时间##
|
|
|
|
|
12号飞机降落了,等了0个单位时间。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##16号时间##
|
|
|
|
|
9号飞机飞走了,等了4个单位时间。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##17号时间##
|
|
|
|
|
11号飞机飞走了,等了3个单位时间。
|
|
|
|
|
13号飞机请求降落,并进入降落队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##18号时间##
|
|
|
|
|
13号飞机降落了,等了0个单位时间。
|
|
|
|
|
14号飞机请求起飞,并进入起飞队伍。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##19号时间##
|
|
|
|
|
14号飞机飞走了,等了0个单位时间。
|
|
|
|
|
历经20个单位时间,机场停止接收请求。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
一共收到了15架飞机的请求。
|
|
|
|
|
一共有4架请求降落。其中有4架被接受了,0架被拒绝了。
|
|
|
|
|
一共有11架请求起飞。其中有11架被接受了,0架被拒绝了。
|
|
|
|
|
|
|
|
|
|
成功降落了4架,还有0架在排队等待降落。
|
|
|
|
|
成功起飞了11架,还有0架在排队等待起飞
|
|
|
|
|
|
|
|
|
|
轨道有25.00%的时间是空闲的。
|
|
|
|
|
降落平均要等0.00个单位时间。
|
|
|
|
|
起飞平均要等0.60个单位时间。
|
|
|
|
|
|
|
|
|
|
这个机场平均每个单位时间收到0.20个降落请求。
|
|
|
|
|
这个机场平均每个单位时间收到0.55个起飞请求。
|
|
|
|
|
————————————————————————————————————————————————————————
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
# 5. 总结
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
通过本次实践作业,我们不但粗浅的了解了泊松分布的含义和使用,对于离散型分布等知识也有了一定的个了解。也更加深入的了解了课堂上的知识,比如结构体和队列的构建与使用。同时经过这次实践作业,我们也初步认识了合作的重要性,和程序设计的实践作业不同,本次数据结构的实践作业明显专业性更强,目的性更加的突出,难度也随之增大,对小组中每个人都有一定的挑战,需要小组成员团结合作,各自发挥自己的长处,从代码,排版,数据的搜集和使用等方面发挥不同的作用。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 参考文献
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[1] CSDN C语言生成符合泊松分布(离散型)的随机数(手写)—— 10生万物
|
|
|
|
|
[2] CSDN 《数据结构与程序设计》队列 case study ——— airport 模拟机场调度 ——超超超超超级菜
|
|
|
|
|
[3] CSDN 【数据结构笔记】 队列的应用——飞机场模拟 ——勇敢琪琪
|