电梯模拟系统文档格式.docx
《电梯模拟系统文档格式.docx》由会员分享,可在线阅读,更多相关《电梯模拟系统文档格式.docx(26页珍藏版)》请在冰豆网上搜索。
电梯加速需要15t
如果电梯在某层静止时间超过300t,则驶回1层候命。
(5)、按时序显示系统状态的变化过程:
发生的全部人和电梯的动作序列。
数据结构
1、乘客类型
反映乘客的所有属性。
ADTClient
数据对象:
D={ai∈乘客信息,I=1,2,…,n,n≥0}
数据关系:
R={<
ai-1,ai>
|ai-1,ai∈D,i=2,…,n}
基本操作:
PrintClientInfo(Clientconst&
e,ClientStatus)
操作结果:
输出乘客信息。
CreatClient(Client*&
p)
生成新的乘客。
DestoryClient(Client*&
该乘客离开系统。
GoAbove(Clientconst&
e)
判断该乘客是否去往高层。
CInfloor(Clientconst&
返回乘客进入的楼层。
CInTime(Clientconst&
返回乘客进入时间。
COutfloor(Clientconst&
}
2、乘客栈类型
电梯内的乘客用乘客栈表示,去不同楼层的乘客放在不同的栈中。
ADTEstack
略。
3、等候队列类型
在电梯外等待的乘客用等待队列表示。
每层各有两个等待队列,分别为上楼队列和下楼队列。
与一般队列不同的是在基本操作中加入了放弃操作CGiveUp(WQueue&
Q,intfloor)。
4、电梯类型
表示电梯的各个属性和所有动作。
ADTElevator
D={ai∈电梯信息,I=1,2,…,n,n≥0}
InitEle(Elevator&
E)
初始化电梯类型。
DestoryEle(Elevator&
销毁电梯类型。
EleDecide(Elevator&
E,WQueuew[Maxfloor+1][2])
电梯动作决策。
ElevatorRun(Elevator&
E,WQueuew[Maxfloor+1][2]){
电梯状态转换。
CountOver(Elevator&
判断电梯计时是否完成。
EleFloor(Elevatorconst&
返回电梯所在的层。
EleStatus(Elevatorconst&
返回电梯状态。
RequireAbove(Elevatorconst&
判断是否有高层请求。
RequireBelow(Elevatorconst&
判断是否有低层请求。
EleAchieved(Elevator&
判断电梯是否要停于当前层。
EleOpenDoor(Elevator&
判断电梯是否要开门。
5、高楼模块
实现电梯和乘客之间的互交功能。
包括:
InOut(Elevator&
进行乘客的进出电梯活动。
NewClient(Elevator&
E,WQueuew[5][2])
进入新乘客。
PrintStatus(Elevator&
输出当前状态。
Print(Elevator&
E,Actiona)
输出电梯动作信息。
算法设计
1:
本程序包含6个模块:
(1)主程序模块
(2)乘客模块
(3)乘客栈模块
(4)电梯模块
(5)等待队列模块
(6)高楼模块:
实现电梯和乘客之间的互交。
各模块之间的调用关系如下:
2:
主程序
主程序主要处理两类事件:
乘客事件和电梯事件。
除此之外,主程序还处理各个模块的初始化和销毁工作,以及电梯状态的输出。
乘客事件包括新乘客到达事件,乘客放弃等待事件,乘客进出电梯事件。
电梯事件包括电梯运行事件。
3:
详细设计
#defineNULL0//空指针
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
#defineOVERFLOW-2
#defineINT_MAX32767
//Status是函数类型,其值是函数结果状态代码
typedefintStatus;
#defineEmpty0
//------------------------------------------------------
//电梯状态
enumEleStatus{Opening,Opened,Closing,Closed,Moving,Decelerate,Waiting};
enumAction{DoorOpened,DoorClosed,GoingUp,GoingDown,Achieved,None};
enumEleStage{Up,Down,OpenDoor,Stop};
enumClientStatus{New,GiveUp,In,Out,Finish};
#defineCloseTest40//电梯关门测试时间
#defineOverTime300//电梯停候超时时间
#defineDoorTime20//开门关门时间
#defineInOutTime25//进出电梯时间
#defineMaxfloor4//最高层
#defineMinfloor0//最低层
longTime=0;
//时钟
longMaxTime;
//系统运行最长时间
intInOutCount=0;
//用于进出计时
intInterTime=0;
//下一乘客进入系统的时间
intID=0;
//乘客编号
intGiveUpNumber=0;
//乘客放弃的数目
intTotalTime=0;
//总共等待时间
部分重要操作的算法:
1、判断运动方向函数EleDecide的算法:
2、统计高层和低层的请求(不包括当前层)。
3、高层和低层均无请求:
发出Stop命令。
4、否则,
1)若电梯在上升期:
1.若有高层请求:
上升;
2.若无高层请求:
转下降期,下降。
2)若电梯在下降期:
1.若有低层请求:
下降;
2.若无有低层请求:
转上升期,上升。
判断电梯是否要停于当前层函数EleAchieved的算法:
1.该层的CallCar为1;
2.该层在上升(下降)期有上升(下降)请求(判断CallUp或CallDown);
3.上升(下降)期高(低)层没有请求而该层由下降(上升)请求,要转换运行时期。
判断电梯动作函数ElevatorRun的算法:
1.若电梯在Opening状态,则转至Opened状态。
2.若电梯在Opened状态,若无人进出,则转至Closing状态。
3.若电梯在Closed状态,则根据电梯请求情况转至相应状态。
4.若电梯在Closing状态,则转至Closed状态。
5.若电梯在Moving状态,若达到目标层,则转至Decelerate状态。
否则,继续移动。
6.若电梯在Decelerate状态,则设定电梯时期,并转至Opening状态。
7.若电梯在Waiting状态,在判断是否等待超时,若超时则向第一层移动。
否则,判断电梯请求情况并转至相应状态。
五:
设计与调试分析
在本程序中如何判断电梯的动作最为关键。
此外,合理划分各个模块和处理各个模块之间的联系也非常重要。
在电梯调度方面不能按照预定的想法实现,所以和现实中的电梯有出入。
没有显示电梯的运行到哪里,而是用有乘客进入电梯时显示乘客进入到哪层楼来告知电梯运行到几楼。
开门,关门时需要精心思考,此处记时及判断是否要开门也是难点,所以这些看似很平常的动作却是最难也是最容易错的地方。
此外在指针的使用方面也是难点,很多地方比如乘客进队出队以及放弃乘坐电梯时均涉及指针的使用,也经常在这些地方通不过编译。
为了便于控制循环,设计了电梯运行时间,则在时间到达时即可退出系统。
由于开始为了简化程序而定义了很多变量,结果发现并不实际,有的变量仅是在某些函数中赋予其值罢了,于是就将这些变量删除,比如开始按照提示设置了D1—表示人们正在进出电梯等等。
体会及建议
我们应重视编程思想的培养,语言很重要,但究竟只是工具,思想才是精髓。
通过阅读书中的各种数据结构及相应算法的代码来吸收书中的思想。
我们可以利用各种途径来学习认识一种功能的实现,但是最终的串联编写还是应该靠自己的思路去不断完善,在这段时间中我们有充分的时间去了解我们完成任务所需的知识内容,而我们也应该去认真完成。
在这阶段的设计过程中,编写时总是出现原来未曾遇到过的各种错误,很难解决,常常受到很长时间的困扰,虽然这属于纯粹的个人能力体现,属于自学运用,但老师并不能在有问题时及时给与有效建议。
而我们的所学有限,考虑问题不是很全面,解决问题也总是难以有高效的解决方案只能通过不断的实践去比较结果。
参考文献
严蔚敏等数据机构(C语言版)清华大学出版社
谭浩强C语言程序设计清华大学出版社
原代码
#include<
stdlib.h>
iostream.h>
iomanip.h>
stdio.h>
windows.h>
conio.h>
time.h>
//所有常量,全局变量和类型定义
#defineNULL0
//乘客类型
typedefstruct{
intClinetID;
//乘客编号
intOutfloor;
//去哪层
intInTime;
//该乘客进入时间
intGivepuTime;
//所能容忍的等待时间
intInfloor;
//乘客进入的楼层
}Client;
//乘客类型基本操作
voidPrintClientInfo(Clientconst&
e,ClientStatuss)
{
switch(s){
caseNew:
printf("
\t%d号乘客进入第%d层.\n"
e.ClinetID,e.Infloor);
break;
caseGiveUp:
\t%d号乘客放弃等待.\n"
e.ClinetID);
caseOut:
\t%d号乘客走出电梯.\n"
caseIn:
printf("
\t%d号乘客走进电梯,要去第%d层.\n"
e.ClinetID,e.Outfloor);
default:
};
StatusCreatClient(Client*&
p)
intd;
p=newClient;
if(!
p)returnOVERFLOW;
p->
ClinetID=++ID;
%d所能容忍的等待时间:
"
ID);
scanf("
%d"
&
d);
GivepuTime=d;
InTime=Time;
下一乘客要到达的时间:
);
InterTime=d;
所要到达的楼层:
Outfloor=d;
while((p->
Infloor=rand()%(Maxfloor+1))==p->
Outfloor);
PrintClientInfo(*p,New);
returnOK;
StatusDestoryClient(Client*&
deletep;
p=NULL;
StatusGoAbove(Clientconst&
e)
if(e.Outfloor>
e.Infloor)returnTRUE;
elsereturnFALSE;
StatusCInfloor(Clientconst&
returne.Infloor;
StatusCInTime(Clientconst&
{
returne.InTime;
StatusCOutfloor(Clientconst&
returne.Outfloor;
#defineSTACK_INIT_SIZE10//存储空间初始分配量
#defineSTACKINCREMENT5//存储空间分配增量
//乘客栈
typedefClient*SElemType;
SElemType*base;
SElemType*top;
intstacksize;
}ClientStack;
StatusInitStack(ClientStack&
S)
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
S.base)returnOVERFLOW;
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
StatusDestroyStack(ClientStack&
S)
SElemType*p;
if(S.base)
for(p=S.base;
p<
S.top;
p++)
DestoryClient(*p);
free(S.base);
}
StatusClearStack(ClientStack&
S.base)returnERROR;
StatusStackEmpty(ClientStackS)
if(S.top==S.base)returnTRUE;
elsereturnFALSE;
StatusStackLength(ClientStackS)
returnS.top-S.base;
StatusGetTop(ClientStackS,SElemType&
e=*(S.top-1);
StatusPush(ClientStack&
S,SElemTypee)
if(S.top-S.base>
=S.stacksize){
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
*S.top++=e;
StatusPop(ClientStack&
S,SElemType&
if(S.top==S.base)returnERROR;
e=*(--S.top);
voidPrintStack(ClientStack&
SElemType*i;
i=S.base;
while(i<
S.top)
cout<
<
(*i++)->
ClinetID<
'
'
;
//电梯类型
intfloor;
//电梯所在层
intClientNumber;
//电梯内人数
EleStatusstatus;
//电梯当前状态
EleStageStage;
//电梯运行时期
intCount;
//用于电梯计时
intCallUp[Maxfloor+1];
//每层的Up按钮
intCallDown[Maxfloor+1];
//每层的Down按钮
intCallCar[Maxfloor+1];
//电梯内的目标层按钮
ClientStackS[Maxfloor+1];
//乘客栈,要去不同楼层的人放在不同的栈中
}Elevator;
//电梯类型基本操作
voidInitEle(Elevator&
E)
inti;
E.floor=1;
E.status=Waiting;
E.Count=OverTime;
E.Stage=Down;
E.ClientNumber=0;
for(i=0;
i<
=Maxfloor;
i++)
E.CallUp[i]=0;
E.CallDown[i]=0;
E.CallCar[i]=0;
i++)InitStack(E.S[i]);
StatusCountOver(Elevator&
if(E.Count){
E.Count--;
returnFALSE;
returnTRUE;
voidDestoryEle(Elevator&
i++)DestroyStack(E.S[i]);
StatusEleFloor(Elevatorconst&
returnE.floor;
EleStatusEleStatus(Elevatorconst&
returnE.status;
StatusRequireAbove(Elevatorconst&
for(inti=E.floor+1;
if(E.CallCar[i]||E.CallDow