18 KiB
机场起降模拟系统
董函铄 胡煜男 于博 袁楷昊
摘要:本项目针对在机场中飞机的降落或起飞问题,实现了对处理的飞机总数进行统计、飞机降落或起飞请求等功能。为了有效地存储和处理飞机总数,请求降落或起飞的飞机数,接受起飞或降落的飞机数,拒绝起飞或降落的飞机数,实际起飞或降落的飞机数等数据,采用了线性表、队列、排序、随机数等数据结构。为了解决时间单位内,飞机的降落或起飞问题,采用了c++、线性表、队列、排序算法,算法效率中等,项目的整体效果较好。
任务分工及完成情况:
任务 | 人员 |
---|---|
文档资料查询 | 胡煜男 、袁楷昊 |
文档汇总 | 董函铄、胡煜男 |
代码资料查询 | 董函铄、于博、袁楷昊 |
代码开发 | 于博、董函铄、胡煜男、袁楷昊 |
代码测试 | 袁楷昊、于博 |
工作量占比:
董函铄 | 胡煜男 | 于博 | 袁楷昊 |
---|---|---|---|
25 | 25 | 25 | 25 |
1. 系统分析
1.1 问题描述
考虑一个繁忙的小型机场仅有一个跑道。在每个单位时间内,只有一架飞机可以降落或起飞,但不能同时进行。随时有飞机准备着降落或起飞,因此在任何给定的时刻,跑道可能是空闲的,或者一架飞机正在降落或起飞,也可能有几架飞机等待着降落或起飞。在模拟中,我们特别关注飞机在起飞或降落时需要排队等待的时间,因此,测量时间对我们的程序至关重要。我们将模拟时间划分为单位,使得在任何给定的时间单位内,只有一架飞机可以利用跑道进行起飞或降落。
1.2 可行性分析
机场只有一个跑道,准备降落的飞机和准备起飞的飞机分别组成一个队列,排队等待降落和起飞。
本项目涉及的对象主要包括飞机、跑道,等待降落和起飞的队列。
1.3 需求分析
(1)输入和输出
输入:
请输入飞机场运行的时间。
请输入降落和起飞队列最多容纳的飞机数。
请输入平均每个单位时间请求降落的飞机数。
请输入平均每个单位时间请求起飞的飞机数。
输出:
x号时间x号飞机降落了,等了x个单位时间。
x号时间x号飞机飞走了,等了x个单位时间。
x号时间没有飞机降落,也没有飞机起飞,此时跑道为空。
x号飞机请求降落,并进入降落队伍。
x号飞机请求降落但被拒绝了。
x号飞机请求起飞,并进入起飞队伍。
x号飞机请求起飞但被拒绝了。
历经d个单位时间,机场停止接收请求。
一共收到了d架飞机的请求。
一共有d架请求降落。其中有d架被接受了,d架被拒绝了。
一共有d架请求起飞。其中有d架被接受了,d架被拒绝了。
成功降落了d架,还有d架在排队等待降落。
成功起飞了d架,还有d架在排队等待起飞。
轨道有d的时间是空闲的。
降落平均要等d个单位时间。
起飞平均要等f个单位时间。
这个机场平均每个单位时间收到f个降落请求。
这个机场平均每个单位时间收到f个起飞请求。
(2)数据字典
飞机场运行时间; 降落和起飞队列最多容纳的飞机数; 平均每个单位时间请求降落的飞机数; 平均每个单位时间请求起飞的飞机数; 每个单位时间内,平均起飞(降落)的飞机数。
(3)数据文件
无数据文件,系统直接产生随机数
(4)参数设定
请输入飞机场运行的时间:24 请输入降落和起飞队列最多容纳的飞机数:6 请输入平均每个单位时间请求降落的飞机数:3 请输入平均每个单位时间请求起飞的飞机数:2 每个单位时间内,平均起飞(降落)的飞机数:系统随机产生
(5)处理已经在队列里的飞机的功能
输出:
##0号时间##
没有飞机降落,也没有飞机起飞,此时跑道为空。
##1号时间##
没有飞机降落,也没有飞机起飞,此时跑道为空。
0号飞机请求降落,并进入降落队伍。
1号飞机请求降落,并进入降落队伍。
2号飞机请求降落,并进入降落队伍。
3号飞机请求降落,并进入降落队伍。
4号飞机请求起飞,并进入起飞队伍。
5号飞机请求起飞,并进入起飞队伍。
6号飞机请求起飞,并进入起飞队伍。
7号飞机请求起飞,并进入起飞队伍。
8号飞机请求起飞,并进入起飞队伍。
###(6)系统汇总功能
输出:
一共收到了106架飞机的请求。
一共有60架请求降落。其中有27架被接受了,33架被拒绝了。
一共有46架请求起飞。其中有6架被接受了,40架被拒绝了。
成功降落了22架,还有5架在排队等待降落。
成功起飞了0架,还有6架在排队等待起飞
轨道有8.33%的时间是空闲的。
降落平均要等3.88个单位时间。
起飞平均要等0.00个单位时间。
这个机场平均每个单位时间收到2.50个降落请求。
这个机场平均每个单位时间收到1.92个起飞请求。
2. 系统设计
2.1 概要设计
系统划分为五个模块,包括随机数的生成和泊松分布的实现,相关数据的输入,处理已经在队列里的飞机,处理请求,数据汇总。
(1)随机数的生成和泊松分布的实现:
随机产生单位时间,随机产生需要处理的飞机总数,随机产生平均起飞或降落的飞机数。
(2)相关数据的输入:
输入飞机场运行的时间、降落和起飞队列最多容纳的飞机数、平均每个单位时间请求降落的飞机数和平均每个单位时间请求起飞的飞机数。
(3)处理已经在队列里的飞机:
根据所给的条件进行判断,输出几号时间几号飞机降落了,等了多少个单位时间或者几号时间几号飞机飞走了,等了多少个单位时间或者几号时间没有飞机降落,也没有飞机起飞,此时跑道为空。
(4)处理请求:
根据条件进行判断,是否同意飞机的降落或起飞请求。如果同意降落,则输出几号飞机请求降落,并进入降落队伍,如果不同意降落,则输出几号飞机请求降落但被拒绝了;如果同意起飞,则输出几号飞机请求起飞,并进入起飞队伍,如果不同意起飞,则输出几号飞机请求起飞但被拒绝了。
(5)数据汇总:
最后统计并输出在本次运行中处理的飞机总数,请求降落的飞机数,请求起飞的飞机数,接受降落的飞机数,接受起飞的飞机数,拒绝降落的飞机数,拒绝起飞的飞机数,实际降落的飞机数,实际起飞的飞机数,仍在等待降落的飞机数,仍在等待起飞的飞机数,跑道空闲时间占比,平均等待降落时间,平均等待起飞时间。
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;
};
2.3 算法设计
(1)排队算法
对于需要进行起降的航班,需要按照先来先服务的原则进行排队。使用队列来实现队列算法,确保飞机的起降顺序正确。
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++;
}
(2)计算时间算法
每个航班的起飞和降落时间是需要进行计算和预测的。可以利用机场容量、飞机起降时间、飞机所属航班等信息来进行计算,预测出每个航班的起飞和降落时间。
Random::Random(bool pseudo)
{
if(pseudo)
seed=1;
else
seed=time(NULL)%INT_MAX;
multiplier=2743;
add_on=5923;
}
3. 系统实现
该程序使用C++语言,主要用到了STL中的queue队列和cmath库中的exp()函数等。开发工具是CodeBlocks和VS Code。
项目的文件结构如下: main.cpp:主程序文件,包含程序的主函数和主要逻辑。 Random.h和Random.cpp:随机数生成的类,包含生成随机数和泊松分布的函数。 plane.h:飞机结构体的定义。 README.md:项目文档,包含程序的介绍和使用说明。 程序的主要函数包括: Random():构造函数,初始化随机数生成器。 random_real():生成0~1之间的随机实数。 poisson():生成泊松分布的随机数。 main():主函数,包含程序的主要逻辑,如输入、处理、输出等。包括两个队列的入队和出队,以及每个飞机的等待时间计算和输出。
3.1 核心数据结构的实现
该程序主要使用了STL中的queue队列来实现飞机的降落和起飞队列。队列是一种先进先出(FIFO)的数据结构,在这里用来存储等待降落和起飞的飞机。 在程序中,定义了两个queue对象,一个用于存储准备降落的飞机,另一个则用于存储准备起飞的飞机。每个队列中存储结构体类型的plane对象,表示每个飞机的编号和进入队列的时间。 在模拟过程中,程序使用队列的push()函数将新到达的飞机加入队列中,使用队列的pop()函数处理已经降落或起飞的飞机。程序还使用队列的empty()函数和front()函数来检查队列是否为空,并获取队列中的第一个元素。
如:
struct plane{
int name;
int in_queue_time;
} plane;
该程序中使用的队列数据结构具有以下特点: 1.先进先出:队列是一种先进先出(FIFO)的数据结构,元素在队列中的顺序是按照进入队列的顺序决定的。在该程序中,飞机进入队列后就不能直接访问,需要按照队列中的顺序依次处理。 2.可以动态增长:队列的容量可以动态增长,队列中的元素数量不受空间限制。 3.可以通过指针实现链式存储:队列可以通过指针实现链式存储,不需要连续的存储空间,因此可以更加灵活地管理内存空间,避免内存浪费。 4.支持入队和出队操作:队列支持入队和出队操作,可以用于实现一些类似于任务派发、消息队列等功能。
3.2 核心算法的实现
该程序的核心算法主要是实现飞机的降落和起飞过程的模拟。具体来说,可以将核心算法分成以下几个部分: 1.生成随机数:程序使用泊松分布的随机数生成算法来模拟飞机的到达时间。该算法需要生成一系列随机实数,因此生成随机数的过程可以看作是核心算法的一部分。 2.处理降落队列:程序在每个单位时间内,会从降落队列中取出第一架等待降落的飞机,并根据降落时间模拟飞机降落的过程。如果降落队列为空,则不进行任何操作。 3.处理起飞队列:程序在处理完降落队列中的飞机后,会从起飞队列中取出第一架等待起飞的飞机,并根据起飞时间模拟飞机起飞的过程。如果起飞队列为空,则不进行任何操作。 4.记录等待时间:程序在处理完每个队列中的飞机后,会记录每架飞机在队列中等待的时间,并累加到总等待时间中。
如:
int main()
{
int time=0,spare_time=0,
wait_time=0, come_wait_time=0 , go_wait_time=0;
int this_time_come=0, this_time_go=0,
total_come=0, total_go=0;
double come_rate=0,go_rate=0;
int total=0,len=0,
come_accepted=0, go_accepted=0;
int i=0, counts=0;
queue <struct plane> q1; //q1是准备降落的飞机队列
queue <struct plane> q2; //q2是准备起飞的飞机队列
struct plane temp;
Random variable;
该算法的时间复杂度为O(n),其中n为模拟的时间,即模拟了n个时间单位。在每个时间单位内,程序需要进行一些基本的操作,如生成随机数、检查队列是否为空、取出队列中的第一个元素等。这些操作的时间复杂度都是O(1),因此程序的总时间复杂度为O(n)。 该算法的空间复杂度为O(m),其中m为队列的最大容量。程序中定义了两个队列,每个队列最多可以存储m 个元素。因此程序的总空间复杂度为O(m)。在程序运行过程中,队列中的元素数量不会超过m,因此空间复杂度是稳定的,不受模拟时间n的影响。需要注意的是,程序中还使用了一些变量来记录总飞机数、总等待时间等信息,但是这些变量的数量较小且与模拟时间无关,因此可以认为它们对空间复杂度的影响可以忽略不计。
4. 系统测试
为了测试该程序的正确性,我们可以采用以下思路和方法: 先使用一组小数据量进行测试,检查程序是否能正常运行并输出正确的结果。 使用多组数据进行测试,包括一些边界值、特殊情况以及大量数据的情况,以检验程序的性能。 对于每组测试数据,记录输入和预期结果,并与程序输出的结果进行比较,以确定程序是否通过测试。 下面给出几个测试用例:
测试用例1:
输入: 10 5 1 1
预期结果: 程序能正常运行,没有任何飞机等待超时。
运行结果:
##0号时间## 1号飞机降落了,等了0个单位时间。
##1号时间## 1号飞机降落了,等了0个单位时间。
##2号时间## 2号飞机降落了,等了0个单位时间。
##3号时间## 3号飞机降落了,等了0个单位时间。
##4号时间## 4号飞机降落了,等了0个单位时间。
##5号时间## 5号飞机降落了,等了0个单位时间。
##6号时间## 6号飞机降落了,等了0个单位时间。
##7号时间## 7号飞机降落了,等了0个单位时间。
##8号时间## 8号飞机降落了,等了0个单位时间。
##9号时间## 9号飞机降落了,等了0个单位时间。
运行结果和预期结果一致,为通过测试。
测试用例2:
输入: 5 2 3 2
预期结果: 程序能正常运行,有一架飞机等待较长时间。
运行结果:
##0号时间## 1号飞机降落了,等了0个单位时间。
##1号时间##
##2号时间## 2号飞机降落了,等了0个单位时间。 1号飞机降落了,等了2个单位时间。
##3号时间## 3号飞机降落了,等了0个单位时间。
##4号时间## 4号飞机降落了,等了0个单位时间。
运行结果和预期结果一致,为通过测试。
特殊情况:
输入的飞机数量为0:如果输入的飞机数量为0,则程序不需要进行任何操作,直接输出所有飞机都已经降落。
输入的飞机数量超过了队列的最大容量:如果输入的飞机数量超过了队列的最大容量m,则程序只会处理前m架飞机,忽略掉超过m架的飞机。
5. 总结
个人小结:
董函铄:在本次课程设计中,再次学习巩固了数据结构的基础知识,包括栈、队列等等;学习了数据结构的算法,例如排序算法;学习了如何规划和组织自己的代码,如何进行测试和调试。但是,学习过程中也遇到了一些问题和挑战。例如,有些算法可能很抽象,需要反复理解和练习,编码中也可能会遇到很多错误和异常情况,需要耐心调试和解决。在我们团队的共同努力和配合下,我们解决了遇到的问题,很好地完成了本次课程设计。
胡煜男:总的来说,这次完成的还算比较顺利。但对于算法的改进和优化方面,需要我们更加深入思考和探索。在团队合作中,我们需要更加密切的沟通和合作,彼此理解和支持,才能解决好问题。
于博:在合作的这段时间里,我学到了很多在学校里没有接触到的东西,而且还掌握了一些实用的技能,这些对我来说都是非常有价值的。通过做这次项目让我感受到了团队浓厚的文化氛围和积极进取的精神。同时,在这段时间里也让我对自己有了一个清醒的认识。当然,在这段制作时间里也遇到一些困难和挫折,但在我们互相的帮助下,这些问题都得到了很好地解决
袁楷昊:在合作的这段时间里,我感受到了非常浓厚的团队精神,掌握了一些实用的技能,这些对我以后非常有帮助,通过团队合作也让我对自身有了较为清楚的认识,还要提高自己的实力,向组里其他人学习,中间也遇到了许多的困难,但我们都能够克服,非常感谢组长以及其他成员,才能完成这项任务。
参考文献
列出参考的文献资料,根据情况自行添加。
[1] 严蔚敏, 吴伟民. 数据结构(C语言版). 北京: 清华大学出版社, 2007. [2] Data Structures and Program Design in C++ (Robert Kruse, Alexander Ryba) (Z-Library) p96 模拟飞机起降