电梯调度
组员:蔡容玉 张丹丹
1 、背景
假设:该大楼有21层,从地面0 , 1 , ... 20 。地板0是地下停车场水平, 1楼是大堂的水平。大多数人都在/走出大楼通过这些2层。
2 、结对开发要求2.1 、每一对学生将设计一套接口和类定义这样一种算法提供者可以提供他/她实现“电梯调度程序”类。2.2 避免出现 “公共汽车”最坏情况的算法。该算法把电梯作为总线,它从底部到顶部,停在每一层楼,打开门,让人们进出,然后把门关上,继续前进。之后到达顶层,它会下去。该算法能够满足所有的要求,但它显然不是最快的算法。2.3 代码要求:它具有生成0 (零)的代码分析警告和错误。它必须是正确的。它要快。
一,概念设计
1.用户界面设计
窗口方式:策略号二选一,用户键盘输入,屏幕输出电梯运行情况以及未响应的请求,hint信息:用户输入指令的方式提示。
2.数据结构设计
2.1常量定义
#define N 3//电梯单层行动时间 #define M 5//电梯停靠楼层时的仿真时间 static int State=1;//电梯初始状态(0停止 1上升 -1下降 -2空闲) static int size=0;//input数组中的元素个数 static Input input[1001];//记录用户的输入请求 static int output[1001]={0};//储存每个仿真时刻电梯状态的数组 static int Time=1;//记录当前的仿真时间 static Output position[1001];//记录电梯的运行情况 static int go=0;//go=1表示GO键被按下,go=0表示GO键未被按下 static int strategy=1;//当前采用的策略号 static int t=0;//t=0表示getinput还不能走 2.2全局数据结构的定义 typedef struct{ int time; char order; int is_done; }Input;//main函数中储存用户指令的结构体数组 typedef struct{ int floor;//前一状态的楼层 int statue;//此时间段内电梯的状态(=0开门 =1上升 =-1下降 =2关门 =-2空闲) }Output;//main函数中记录电梯输出情况的结构体数组
3.函数说明 void getinput(void)//接收输入 void state_d(void)//确定电梯状态 void print_s(void)//输出电梯状态 void control(void)//确定下一个楼层 void time_control(void)//控制时间 int find(Input *,int,int,int,int [][20],int *)//查找请求序列中的下一个目标楼层 void Order(void)//打印剩余的指令 int newd(int [][20],int,int *,int)//确定新的运行方向 int finish(Input,int,int,int)//消除命令 int trans(char)//转化为数字楼层 void clear(void);//清屏函数 void locate(int,int)//定位到第y行的第x列 int assist(int,int,int *,Input,int)//顺便服务策略 int orders(int,Input,int,int,int *)//先来先服务策略 int ask(char)//判断是否是重复的指令 void hint(void)//打印用户输入指令提示 int legal(char)//判断输入是否合法
详细设计:
一.电梯配置 1. 2至20层每层有上下两个按钮,1层只有上行按钮,20层只有下行按钮。每层都有相应的指示灯,灯亮表示该按钮已经被按下,如果该层的上行或者下行请求已经被响应,则指示灯灭。 2. 电梯内共有20个目标按钮,表示有乘客要在该层下电梯。有指示灯指示按钮是否被按下。乘客按按钮导致按钮指示灯亮,如果电梯已经在该层停靠则该按钮指示灯灭。 3. 另有一启动按钮(GO)。当电梯停在某一楼层后,接受到GO信息就继续运行。如果得不到GO信息,等待一段时间也自动继续运行。 4. 电梯内设有方向指示灯表示当前电梯运行方向。 二.电梯运行的控制策略 顺便服务策略:顺便服务是一种最常见的简单策略。这种策略在运行控制中所规定的安全前提下,一次将一个方向上的所有呼叫和目标全部完成。然后掉转运行方向完成另外一个方向上的所有呼叫和目标。可以采用设定目标楼层的办法来实现这个策略,即电梯向一个目标楼层运行,但这个楼层可以修改。
状态转换函数: void state_d()//确定电梯状态 { position[Time].floor=output[Time]; if(output[Time+1]==output[Time])//下一个时刻和当前时刻的电梯层数相同(不移动) { int flag=0;//等待GO时间 go=0; position[Time].statue=0; while(go==0&&flag<=3)//GO键还没有被按下 { clear(); print_s(); Order(); hint(); Sleep(3000); Time++; output[Time+1]=output[Time]; position[Time].floor=output[Time]; position[Time].statue=0; flag++; } position[Time].statue=2;//内部需求满足后关上门 go=0; } else if(output[Time+1]==100*output[Time]||State==-2)//电梯处于空间状态 { State=-2; output[Time+1]=output[Time]; position[Time].statue=-2; } else if(output[Time+1]>output[Time])//电梯要上升 { State=1; position[Time].statue=1; } else//电梯要下降 { State=-1; position[Time].statue=-1; } }
由于限制,只粘贴部分代码:
int assist(int out[],int time,int *direction,Input in[],int in_size)//顺便服务策略:0停止 1上升 -1下降 -2空闲 { int keyinfo[3][20]={0},floor=out[time]-1,d=-2;//存储键盘输入信息,[1][]内部请求,[2][]外部丄行请求,[0][]外部下行请求,[][n]n+1层,1被选,0未被选 int find(Input *,int,int,int,int[][20],int *); int newd(int[][20],int,int *,int); int finish(Input in[],int direction,int floor,int size); if(!find(in,in_size,time,floor,keyinfo,&d))//空 { *direction=-2; out[time+1]=100*out[time]; return -2;//置电梯于空闲状态 } else//非空 { newd(keyinfo,floor,&*direction,d); if(keyinfo[1][floor]||(keyinfo[0][floor]&&*direction==-1)||(keyinfo[2][floor]&&*direction==1))//需要停靠 { out[time+1]=out[time];//下一时刻与上一时刻同一位置 keyinfo[1][floor]=0;//将该指令标记为"已执行" if(*direction==-2) keyinfo[0][floor]=keyinfo[2][floor]=0; else keyinfo[1+*direction][floor]=0; finish(in,*direction,floor,in_size); return 0;//0指需要暂停 } else//不需要停靠,电梯将要移动 { if(*direction==-2)//停一会儿 *direction=d;//新方向为最先指令所在方向(若无指令则不改变) if(*direction==-2) { out[time+1]=out[time];//下一时刻与上一时刻同一位置 return *direction;//不移动返回-2 } else//将要移动 { out[time+1]=out[time]+*direction; return *direction; }//向当前运行方向移动一层 } } }
int find(Input *in,int size,int curTime,int floor,int keyinfo[][20],int *d)//查找请求序列中的下一个目标楼层 { int i,j,empty=0;//0指空 for(i=1;i<=size;i++) if(!in[i].is_done&&in[i].time<=curTime) { int is_finished=0,ifFirst=1;//0指未完成指令,1指完成指令 for(j=0;j<27;j++) if(xiaoxie[j]==in[i].order) { if(!(j%20==floor&&curTime-1==in[i].time)) { keyinfo[j/20][j%20]=1; is_finished=1; empty=1; } if(ifFirst) if(j%20>floor) { *d=1; ifFirst=0; } else if(j%20<floor) { *d=-1; ifFirst=0; } break; } if(!is_finished) for(j=0;j<27;j++) if(daxie[j]==in[i].order) { if(!(j%20==floor&&curTime-1==in[i].time)) { keyinfo[j/20][j%20]=1; empty=1; } if(ifFirst) if(j%20>floor) { *d=1; ifFirst=0; } else if(j%20<floor) { *d=-1; ifFirst=0; } break; } } return empty; }
运行结果:
以上!谢谢!