电梯模拟 数据结构课设

代码:

https://download.csdn.net/download/TYtrack/19384997

报告:

https://download.csdn.net/download/TYtrack/19384997

 

目录

 

 

一、课程设计题目与要求

1、题目内容

2、题目要求

二、需求分析

1、总体功能需求

2、功能需求

3、软件开发平台需求

4、输入输出要求

三、设计

1、设计思想

1、数据结构设计

2、算法设计

2、设计表示:

1、函数调用关系图

2、函数接口规格说明

3、详细设计

四、调试分析

1、遇到主要的问题:

2、程序的时空复杂度分析:

3、经验体会:

五、用户手册

六、测试数据及测试结果


 

一、课程设计题目与要求

1、题目内容

模拟某校九层教学楼的电梯系统。该楼有一个自动电梯,能在每层停留,其中第一层是大楼的进出层,即是电梯的“本垒层”,电梯“空闲”时,将来到该层候命。

电梯一共有七个状态,即正在开门(Opening)、已开门(Opened)、正在关门(Closing)、

已关门(Closed)、等待(Waiting)、移动(Moving)、减速(Decelerate)。

乘客可随机地进出于任何层。对每个人来说,他有一个能容忍的最长等待时间,一旦等候电梯时间过长,他将放弃。

模拟时钟从 0 开始,时间单位为 0.1 秒。人和电梯的各种动作均要消耗一定的时间单位(简记为 t),比如:

有人进出时,电梯每隔 40t 测试一次,若无人进出,则关门;

关门和开门各需要 20t;

每个人进出电梯均需要 25t;

电梯加速需要 15t;

上升时,每一层需要 51t,减速需要 14t;

下降时,每一层需要 61t,减速需要 23t;

如果电梯在某层静止时间超过 300t,则驶回 1 层候命。

2、题目要求

基本:按时序显示系统状态的变化过程,即发生的全部人和电梯的动作序列。

扩展:实现电梯模拟的可视化界面。

 

二、需求分析

1、总体功能需求

该作品将实现一个模拟电梯,在界面上显示出电梯系统状态的变化过程,即发生的全部人和电梯的动作序列,对于乘客而言,动作包括等待电梯到来、进出电梯以及由于等待时间过长而离开电梯,对于电梯而言,动作包括电梯的加减速、上升与下降、开门与关门以及由于在某一层停留时间过长而驶回1层。其中要求乘客的产生是随机的,电梯有一定的载荷量,当超过载荷量的时候,电梯外乘客无法进入。

2、功能需求

能够模拟出正常电梯的行为以及状态,能够计算并打印出当前时间电梯的行为是必要的

3、软件开发平台需求

开发者开发的软件要求能够正常运行在Windows平台,且具有一定的平台兼容性.。为保证软件的上下兼容性,开发者应选择通用的开发工具的来进行开发,目前的开发软件平台为Visual Studio 2016。

4、输入输出要求

该系统无需对其进行输入,用户只需运行,乘客的产生以及各信息由程序随机产生;

系统的输出为电梯系统状态的变化时间过程以及各乘客的动作序列过程,并打印出当前时间,如:

乘客1想做电梯,来自第9楼,去第2楼              现在时间:483

       电梯准备去9楼   电梯经过3楼                     现在时间:287

三、设计

1、设计思想

1、数据结构设计

主要存储结构为类和链表;

电梯内的乘客和电梯外等待的乘客分别由两个链表存储,使用链表存储能够更容易地对乘客进行出入操作,并且可以帮助,当电梯在未超载的前提下,到达某楼层,满足可进电梯条件之后,将该乘客从等待链表中删去,又加入到电梯内乘客的链表中。

乘客和电梯封装成类,其中乘客类的属性包括了乘客的基本信息,包括等待时间、所来和所去楼层以及唯一编号;

电梯类的属性包括电梯从开始运行的时间、存储电梯内外的乘客的两个列表、电梯当前状态以及处于当前状态的时间、上次和当前以及目的楼层、现在电梯运行方向等。其方法包括自定义构造函数、随机产生乘客、主时间函数、乘客进出电梯函数、乘客离开电梯函数、用户因为等待时间过长离开、电梯判断可关门函数、电梯返回一楼函数等;

值得注意的是这里无论是电梯的状态还是乘客的状态都是枚举类型,好处是方便直观。

2、算法设计

该系统可分为产生乘客、乘客进出电梯模块、电梯关门及运动、回到一楼、目的楼层计算五个模块,模拟时钟的运行依次照着这五个模块的次序而运转,接下来会详细介绍这五个模块:

  • 产生乘客模块:

本模块使用随机函数产生乘客,经过测试可得到,平均每100t产生一名乘客较合理,因此,我们对于每1t产生一个随机数,并对结果模上100,若为0则产生乘客,反之不成立。当确定产生乘客时,随机产生乘客的其他信息,譬如乘客当前所在楼层和目的楼层,对其状态设为等待电梯状态并开始计时。

  • 乘客进出电梯模块:

调用此模块之前,需要对当前是否能够开门进行判断,判断可行之后,延时20t来表示开门的20t,此后,再对人进入电梯以及离开电梯进行操作,并将当前楼层修改为之前的目的楼层。

 

  • 电梯的关门模块:

调用此模块之前,需要对当前是否能够关门进行判断,与上一模块不同的是确定关门之后,每40t判断一次,而不是每时每刻都在判断,关门之后,将当前状态设为waiting或上行、下行,而当前状态时间设为0。

 

  • 回到一楼模块

该模块相对而言较简单,如果电梯在某层静止时间超过 300t,则驶回 1 层候命,判断可行时,将目的楼层设为1。

 

  • 目的楼层计算与到达模块

该模块首先会根据当前电梯运转方向、电梯外乘客所在楼层、电梯内乘客的目的楼层来判断是否继续该方向的运转,如果满足,选择最靠近当前楼层的楼层为目的楼层,若不满足,比如,之前电梯方向为上,但是电梯没有想去更高楼层的乘客,电梯外也没有更高楼层的乘客在等侯,这时候,电梯应该考虑向下运转,之后,我们再根据计算结果到达目的楼层。

下图为主程序的流程图:

图1 主程序的流程图

 

2、设计表示:

1、函数调用关系图

2、函数接口规格说明

 

Elevator()

说    明:重写电梯类的构造函数,初始化电梯的所有参数。

参    数:无

返 回 值:无

 

void Random_Man();

说    明:平均每100t随机产生一名乘客,并在该函数中实现乘客的信息随机产生,除此外,还有判断电梯外乘客是否离开,以及通过乘客决定目的楼层。

参    数:无

返 回 值:无

 

       void Time_();

说    明:电梯的模拟时钟函数,作为主函数中循环调用的函数,并在其内部一次调用其它模块。

参    数:无

返 回 值:无

 

       void entryElevator();

说    明:乘客进入电梯函数 : 在电梯开门后,将满足进入电梯的乘客信息从等待链表中删除,并添加到电梯内部乘客链表中。

参    数:无

返 回 值:无

 

       void leaveElevator();

说    明:乘客离开电梯函数 : 在电梯开门后判断电梯内的乘客是否满足离开电梯的条件,将其信息删去。

参    数:无

返 回 值:无

 

       int canBackToOne();

说    明:判断电梯是否满足因为等待时间过长而回到一楼的条件。

参    数:无

意义

0

不满足自动返回一楼的条件

1

满足自动返回一楼的条件

void manLeave();

说    明:对电梯外的乘客依次进行判断是否由于等待时间过长而停止等待

参    数:无

返 回 值:无

 

       int isPause();

说    明:通过计算来判断当前电梯是否已到达目的楼层。

参    数:无

返 回 值:

意义

0

电梯未到目的楼层

1

电梯已到目的楼层

 

 

       void Pause();

说    明:当电梯到达到目的楼层之后进行的一系列操作,包括开门、乘客的进入与离开。

参    数:无

返 回 值:无

 

       int pre_Moving();

说    明:计算电梯当前的目的楼层。

参    数:无

返 回 值:返回当前电梯的目的楼层。

 

       int canClose();

说    明:判断电梯当前是否可以进行关门操作。

参    数:无

返 回 值:

意义

0

电梯不可关门

1

电梯可关门

 

       void Close();

说    明:当电梯准备关门之后进行的一系列操作,包括关门,以及电梯的方向决定。

参    数:无

返 回 值:无

 

       int UpStairs();

说    明:计算得到电梯内乘客所想去的最高楼层。

参    数:无

返 回 值:返回电梯内乘客所想去的最高楼层。

 

       int DownStairs();

说    明:计算得到电梯内乘客所想去的最低楼层。

参    数:无

返 回 值:计算得到电梯内乘客所想去的最低楼层。

 

3、详细设计

1、电梯状态

/**

*   将电梯的状态设为枚举类型,简单直观

*/

enum Status {

         Opening = 1, Opend, Closing, Closed, Waiting, Down_Moving,Up_Moving, Decelerate, Accelerate

};

2、乘客类:

/**

*   定义一个乘客的所有信息

*/

class Man {

public:

         int num;

         int from;

         int to;            //去哪里

         int Time;          //等待时间

         Status_Man Status;  //只有等待和不等待

};

3、电梯类:

/**

*   自定义的一个模拟电梯类

*/

 

数据成员:

public:

         list<Man> Pass;     //电梯外等待的乘客

         list<Man> now_Pass;//电梯内的乘客

         int time;           //电梯已经运行的时间

         int now_Floor;      //上次电梯开门的楼层

         int next_Floor;      //电梯的目的楼层

         Status now_Status;   //电梯当前状态

         int before;          // 1:之前是向上的  0:之前向下

         int parm_Floor;     //当前所处楼层

         int now_Status_Time; //当前状态已花时间

 

四、调试分析

1、遇到主要的问题:

1)     在使用STL对链表里面的元素进行删除时,总是造成不可预期的错误,因为erase之后,链表更新,迭代器可能发生错误,之前在这个问题上停留了很久,最终通过阅读《STL源码剖析》找到了解决方案,先判断迭代器是否为最后一个元素,若不是,则使用erase(),若是,则使用pop_back()。

2)    对该模拟电梯进行设计的时候,因为电梯需要逻辑判断和行为实施同时进行,比如需要在电梯上下运行的同时,不能影响乘客的产生,同时还需要判断是否到达目的楼层,一开始所想的是使用多线程编程,但是C++对多线程很不友好,需要对windows底层进行编程,比较麻烦,因此,最后通过sleep()暂时休眠进程来对每一个t进行实际操作。

3)     在计算下一个目的楼层的时候,通过pre_Moving()计算之后的结果总是与实际结果不一样,具体表现在当电梯某一楼层时,突然显示到了第14层,通过单步断点,最后发现是计算当前楼层发生了逻辑错误,修改代码之后,将当前楼层加入到类的属性之中,防止接下来的代码编写出现类似问题。

4)       显示电梯和用户的动作序列时,之前是将其直接输出,最后显示的太过混乱,电梯行为和用户的行为序列互相混淆,因为没有使用图形化界面,最后解决办法是将电梯的行为输出到屏幕左边,乘客的行为输出到右边,中间显示电梯的时间,同时在关于给每一个人一个标识的时候,为了达到标识与记录两种功能,最后选择使用全局数字序号,因为它简洁,能够产生的标识多而且相比较而言更容易实现。

2、程序的时空复杂度分析:

该系统的运行时间是无穷的,当开始启动之后,电梯的每时每刻都在运行或者等待操作,因此在讨论复杂度的时候是对每一个时间t所要完成的任务作复杂度分析,对于本程序,使用最多的算法是对链表的操作,主要是插入和删除操作,因为插入操作是直接在链表的头指针直接插入的时空复杂度均为O(1),因此最高的时间复杂度就是对链表的删除操作,其时间复杂度为O(n),空间复杂度为O(1),其中n为链表的长度。对于其他操作,如计算目的楼层时,需要对链表中的元素进行遍历,通过分析,时间复杂度为O(n),空间复杂度为O(1),实际情况下,由于每t都有可能随机产生1名乘客,但是乘客的最大等待时间是300t,因此电梯外乘客的链表不会超过300,而电梯内乘客链表由于电梯负载限制最多容纳13人。

3、经验体会:

       1) 我认为使用多线程编程能使得该系统更简单: 用虚拟时钟,自己设置一个相对时间,每进行一个动作就将这个动作所用的时间加到一个全局变量中,并且每进行一个动作就将该动作的执行内容输出,通过并行操作之后,实际中的t和编码之后的t是一样的,但是在该系统之中,题目所要求得t和该系统的t是有所不同的,但是C++多线程的处理过程很让人费解,因为对于本道题我更倾向于使用Java,因为对Java的多线程有比较深的理解,可以将本道题没有使用多线程的缺陷运用上去。

       2)    理解分析问题的能力得到提高。设计一个应用程序关键是对要求做最准确的把握,也就是说弄清楚需求分析是很重要的。这道题刚开始看,很难理解这道题要达到的目的是什么,如何通过模拟时钟来告知各模块应执行什么操作,同时又要对乘客的进入进行操作,这之间的过程很让人费解,经过仔细的多次读题后,画了个草图,才理清其中的思路。所以,通过这道题,大大提高了我的理解分析问题能力。

 

五、用户手册

1.打开文件

windows环境下双击执行文件 zzz_eleva.exe。

2.运行:

       (1)界面左边显示的是电梯的动作序列,比如当前楼层、目标楼层和当前方向,或者是电梯的开门、关门、加速和减速等等;

       (2)界面右边显示的是乘客的动作序列,包括乘客的随机产生成功、乘客因等待时间过长而离去、乘客进入或离开电梯;

(3)界面中间显示的是当前电梯运行的时间,单位是t。

 

3.退出:

在任意时刻,操作者都可点击右上角的“X”来退出电梯模拟。

 

六、测试数据及测试结果

测试输入:

数据是程序随机生成,包括产生乘客的时间和楼层信息:

电梯时间

乘客编号

来自楼层

目的楼层

4t

乘客1

9

2

155t

乘客2

3

7

183t

乘客3

9

2

199t

乘客4

3

5

267t

乘客5

9

7

452t

乘客6

7

2

504t

乘客7

2

5

 

测试目的:

1)电梯是否能够正常运行;

2)电梯时间是否正常。

3)乘客是否能够在等待时间内乘坐电梯,并在目的楼层离开电梯;

 

正确输出:

                                  现在时间:4             乘客1想做电梯,来自第9楼,去第2楼

电梯准备去9楼   电梯经过1楼  ↑ 现在时间:19

电梯准备去9楼   电梯经过2楼  ↑ 现在时间:70

电梯准备去9楼   电梯经过3楼  ↑ 现在时间:121

                                  现在时间:155            乘客2想做电梯,来自第3楼,去第7楼

电梯准备去9楼   电梯经过4楼  ↑ 现在时间:172

                                  现在时间:183            乘客3想做电梯,来自第9楼,去第2楼

                                  现在时间:199            乘客4想做电梯,来自第3楼,去第5楼

电梯准备去9楼   电梯经过5楼  ↑ 现在时间:223

                                  现在时间:267            乘客5想做电梯,来自第9楼,去第7楼

电梯准备去9楼   电梯经过6楼  ↑ 现在时间:274

                                  现在时间:300                    1号乘客等待时间过长离开

电梯准备去9楼   电梯经过7楼  ↑ 现在时间:325

电梯准备去9楼   电梯经过8楼  ↑ 现在时间:376

电梯准备去9楼   电梯经过9楼  ↑ 现在时间:427

                                  现在时间:441

电梯已到9楼

1电梯在开门                       现在时间:441

                                  现在时间:452            乘客6想做电梯,来自第7楼,去第2楼

现在楼层在9                       现在时间:461

                                  现在时间:470

电梯已到9楼

1电梯在开门                      现在时间:470

                                  现在时间:490            5号乘客从9楼进入电梯,想去7楼

电梯进人ing

                                 现在时间:504            乘客7想做电梯,来自第2楼,去第5楼

                                 现在时间:504                    2号乘客等待时间过长离开

                                 现在时间:509            乘客8想做电梯,来自第4楼,去第5楼

                                 现在时间:515            3号乘客从9楼进入电梯,想去2楼

电梯进人ing

现在楼层在9                       现在时间:540

电梯准备去7楼   电梯经过8楼  ↓ 现在时间:546

                                  现在时间:585                    4号乘客等待时间过长离开

电梯准备去7楼   电梯经过7楼  ↓ 现在时间:607

 

实际输出:

 

 

 

 

 

 

 

 

 

  • 18
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
设计一个电梯模拟系统。这是一个离散的模拟程序,由随机事件驱动,以模拟时钟决定乘客或电梯的动作发生的时刻和顺序,系统在某个模拟瞬间处理有待完成的各种事情,然后把模拟时钟推进到某个动作预定要发生的下一时刻。 要求: (1)模拟某校九层教学楼的电梯系统。该楼有一个自动电梯,能在每层停留,其中第一层是大楼的进出层,即是电梯的“本垒层”,电梯“空闲”时,将来到该层候命。 电梯一共有八个状态,即正在开门(Opening)、已开门(Opened)、正在关门(Closing)、已关门(Closed)、等待(Waiting)、移动(Moving)、加速(Accelerate)、减速(Decelerate)。 (2)乘客可随机地进出于任何层。对每个人来说,他有一个能容忍的最长等待时间,一旦等候电梯时间过长,他将放弃。最后一个人放弃能不能取消按键? (3)模拟时钟从0开始,时间单位为0.1秒。人和电梯的各种动作均要消耗一定的时间单位(简记为t),比如: 有人进出时,电梯每隔40t测试一次,若无人进出,则关门; 关门和开门各需要20t; 每个人进出电梯均需要25t; 电梯加速需要15t; 下行时要不要加速? 上升时,每一层需要51t,减速需要14t;每一层和减速? 下降时,每一层需要61t,减速需要23t; 如果电梯在某层静止时间超过300t,则驶回1层候命。驶回本垒层间接到消息? (4)电梯调度规则如下: ①就近原则:电梯的主要调度策略是首先响应沿当前行进方向上最近端的请求直到满足最远端请求。若该方向上无请求时,就改变移动方向; ②在就近原则无法满足的情况下,首先满足更高层的请求; ③电梯的最大承载人数为13人,电梯人数达到13人后,在有人出电梯之前,不接受进入电梯的请求; ④乘客上下电梯时先出后进。进电梯时乘客是按发出乘坐请求的顺序依次进入,每次只能进入一人且每个人花费的时间都为25t; ⑤电梯在关门期间(电梯离开之前)所在层提出请求的乘客同样允许进入。 (5)按时序显示系统状态的变化过程,即发生的全部人和电梯的动作序列。 扩展要求: 实现电梯模拟的可视化界面。用动画显示电梯的升降,人进出电梯。设计有下列对象:电梯、人、电梯控制板及其上各种按钮、模拟时钟等。
建立一座两层楼,一部电梯模拟程序。为简化起见,每部电梯限乘一人,电梯每天在一楼关门等待。 三、具体要求及应提交的材料 模拟程序包括一个时钟,每天从零开始。模拟程序得调度器组件随机设置每一层第一个人到来的时间,当时钟的时间等于第一个人到来的时间时,模拟程序生成一个新到的人将该人放到这一层。然后这个人按下按钮,请求电梯开门。这个人的目的地楼层不能与他上电梯的楼层相同。 如果第一个人到达第一层,则可以在按下按钮、等待电梯开门之后立即进入电梯。如果第一个人在第2层,则电梯要升到第2层去接他。电梯从1层移到2层需要5秒。 电梯到达一层时,打开电梯门上的灯,并在电梯内发出铃声,该层的按钮和电梯中表示该层的按钮复位,电梯门打开,乘客走出电梯(如果有到该层的乘客)。另一乘客(如果该层有人等待)进入电梯按下目的层按钮,电梯们关上。电梯移动前确定移动方向(两层很容易判断),为简单起见,电梯到达一层直到关门所花时间为0。 任何时间每层最多只能有一人等待,如果新到的人(不在电梯中)要到达该层时该层被占用,则一秒后才能安排新到达者。假设每隔5到20秒人们随机到达每层。 要求: 对每个(building,floor,elevator,person,button,time)设计 一个头文件,存放定义,建立一个程序,存放的实现。例如floor.h,floor.cpp 输出结果用文字表示即可,如“Person1 arriveds on Floor1, Person 1 enters Elevator”等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值