导航:首页 > 源码编译 > 如何设计电梯算法

如何设计电梯算法

发布时间:2024-01-08 02:24:27

1. 电梯算法是怎样的

电梯算法是通过操作系统学术名为SCAN算法。磁臂仅移动到请求的最外道就回转。反方向查找服务。

如果请求调度的磁道为98, 183, 37, 122, 14, 124, 65, 67,磁头从53号磁道开始移动,磁头就会按照65, 67, 98, 122, 124, 183, 37,14 的顺序依次查找,并将数据输入内存。

电梯(升降盒)上下来回地运动,电梯内部有一些按钮,每一个按钮代表一层楼,当按下按钮时,按钮的灯亮。

电梯沿某一方向运动,在将要到达某一层楼时,实时监控器 判断电梯内是否有乘客要在此层楼下电梯,若有,则发送信号给电梯升降架。

电梯是指服务于建筑物内若干特定的楼层,其轿厢运行在至少两列垂直于水平面或与铅垂线倾斜角小于15°的刚性轨道运动的永久运输设备。

也有台阶式,踏步板装在履带上连续运行,俗称自动扶梯或自动人行道。服务于规定楼层的固定式升降设备。垂直升降电梯具有一个轿厢,运行在至少两列垂直的或倾斜角小于15°的刚性导轨之间。

轿厢尺寸与结构形式便于乘客出入或装卸货物。习惯上不论其驱动方式如何,将电梯作为建筑物内垂直交通运输工具的总称。

2. java模拟实现两部电梯同时工作的高效算法

1. 各电梯控制:
a. 实现一个方法,返回本电梯到请求楼层上、下的时间(或者简单点的,层数);
b. 任务接受:接受用户楼层上、下请求任务

2. 主控部分:
a. 当用户按下上、下请求时,通过调用两个电梯的上面所说的服务,进行比较决断最优时间电梯;
b. 给最最优电梯发送任务;
3. 主控与各电梯控制之间的通讯可以通过多种方式实现;

3. 请问谁有C语言的电梯模拟算法

#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>
#include <winbase.h>
#include <string.h>
#include "egg.h"
#include "elevator.h"

#define START 0//定义初始状态
#define UP 1//上行初始
#define DOWN 2//下行初始
#define PAUSE 3
#define N 100//记录数组的容量

void getInput(void);//
void getInput0(void);//

void Status_trans(void);//显示当前的状态
void control(void);//控制主要的电梯过程
void control0(void);//在暂停后的控制
void time_count(void);
void Uper(void); //上行
void Downer(void); //下行

int Call[N]={0};
int Callup[10]={0}; //存放向上呼叫的整型数组
int Callin[10]={0}; //存放内部呼叫的整型数组
int Calldown[10]={0};//存放向下呼叫的整型数组
int time=0,state=0,prestate=0,flag=1,x=0;
int aimLayer=0,currentLayer=1;
float cl1=0.0,cl2=0.0;

main()
{
int service;
elevator();

system("color 3f");

printf("EVA 电梯竭诚为您服务,祝乘坐愉快\n");
printf("请选择服务策略(1为先来先服务,2为顺便服务):\n");
scanf("%d",&service);
if(service==1) {
DWORD ThreadID1 = 1;
HANDLE hRead1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)getInput0,NULL,0,&ThreadID1);
}
else {
DWORD ThreadID2 = 1;
HANDLE hRead2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)getInput,NULL,0,&ThreadID2);
}
while (1){
if(service==1)
control0();
else
control();
Status_trans(); /*确定电梯此刻的状态,包括运行方向、所在楼层等*/

}

system("pause");
return 0;
}

void Status_trans(void)//yang
{
int i;

switch (state) {
case START:
if(aimLayer>currentLayer)
state=UP;
if(aimLayer==currentLayer)
state=PAUSE,prestate=START;
if(aimLayer==0)
state=START;
break;
case UP:
flag=1;

Uper();
currentLayer++;
drawCurrentLayer1(currentLayer);
drawCurrentLayer2(currentLayer);
printf("当前电梯楼层 %d\n", currentLayer);
if(currentLayer==aimLayer) {
state=PAUSE,x=1,prestate=UP;
printf("当前电梯楼层 %d\n", currentLayer);
}
if(currentLayer<aimLayer)
state=UP,flag=1;
if(currentLayer>aimLayer)
state=DOWN,flag=-1;
break;
case DOWN:
flag=-1;

Downer();
currentLayer--;//?
drawCurrentLayer1(currentLayer);
drawCurrentLayer2(currentLayer);
printf("当前电梯楼层 %d\n", currentLayer);
if(currentLayer==aimLayer) {
state=PAUSE,x=1,prestate=DOWN;
printf("当前电梯楼层 %d\n", currentLayer);
}
if(currentLayer<aimLayer)
state=UP,flag=1;
if(currentLayer>aimLayer)
state=DOWN,flag=-1;//flag?
break;
case PAUSE:
drawCurrentLayer1(currentLayer);
drawCurrentLayer2(currentLayer);
for(i=1;i<=4;i++)
WaitFor(100);
if(aimLayer<currentLayer)
state=DOWN;
if(aimLayer>currentLayer)
state=UP;
if(aimLayer==0)
state=PAUSE,prestate=PAUSE;
break;
}
}

void control(void)
{
int i,mark=0,m=0;

if(flag==1) {
if(state==PAUSE && prestate!=PAUSE) {//上行中确定目标楼层
Callin[currentLayer]=Callup[currentLayer]=0;
for(i=currentLayer+1;i<=9;i++)
if(Callup[i]==1 || Callin[i]==1 || Calldown[i]==1)
m=1;
if(m!=1)//无上行需求直接将下行此楼层处理
Calldown[currentLayer]=0;
}
for(i=currentLayer;i<=9;i++)
if(Callup[i]==1 || Callin[i]==1) {
mark=i;
aimLayer=i;
break;
}//有上行需求 ,目标楼层被确定
if(mark==0)//无上行需求
for(i=9;i>=1;i--)
if(Calldown[i]==1 || Callin[i]==1) {
aimLayer=i;
mark=i;
break;
}//确定下行目标楼层
if(mark==0)
for(i=1;i<=8;i++)
if(Callup[i]==1) {
aimLayer=i;
mark=i;
break;
}
if(mark==0)
aimLayer=0;
}//无目标楼层
else if(flag==-1) {
if(state==PAUSE && prestate!=PAUSE) {//电梯运行中
Calldown[currentLayer]=Callin[currentLayer]=0;//此层已处理过
for(i=currentLayer-1;i>=1;i--)
if(Callup[i]==1 || Callin[i]==1 || Calldown[i]==1)
m=1;
if(m!=1)
Callup[currentLayer]=0;//无目标楼层暂时停靠 m??
}
for(i=currentLayer-1;i>=1;i--)
if(Calldown[i]==1 || Callin[i]==1) {
mark=i;
aimLayer=i;
break;
}//确定下行目标楼层

//???为何要向上运行开始呢?

if(mark==0) //顺便无要求,开始新的一楼起的上升需求扫描
for(i=1;i<=9;i++)
if(Callup[i]==1 || Callin[i]==1) {
aimLayer=i;
mark=i;
break;
}
if(mark==0)
for(i=9;i>=2;i--)
if(Calldown[i]==1) {
aimLayer=i;
mark=i;
break;
}
if(mark==0)
aimLayer=0;
}
}

void control0(void)//yang
{
int i;

for(i=0;i<=N-1;i++) {
if(Call[i]!=0) {
aimLayer=Call[i];
if(state==PAUSE && prestate!=PAUSE)
Call[i]=0;
break;
}
}
}

void getInput(void)
{
char ch;

while(1){
ch=getchar();
switch(ch) {

case'I':
Callup[1]=1;
break;
case'U':
Callup[2]=1;
break;
case'Y':
Callup[3]=1;
break;
case'T':
Callup[4]=1;
break;
case'R':
Callup[5]=1;
break;
case'E':
Callup[6]=1;
break;
case'W':
Callup[7]=1;
break;
case'Q':
Callup[8]=1;
break;

case'K':
Calldown[2]=1;
break;
case'J':
Calldown[3]=1;
break;
case'H':
Calldown[4]=1;
break;
case'G':
Calldown[5]=1;
break;
case'F':
Calldown[6]=1;
break;
case'D':
Calldown[7]=1;
break;
case'S':
Calldown[8]=1;
break;
case'A':
Calldown[9]=1;
break;

case '1':
Callin[1]=1;
break;
case '2':
Callin[2]=1;
break;
case '3':
Callin[3]=1;
break;
case '4':
Callin[4]=1;
break;
case '5':
Callin[5]=1;
break;
case '6':
Callin[6]=1;
break;
case '7':
Callin[7]=1;
break;
case '8':
Callin[8]=1;
break;
case '9':
Callin[9]=1;
break;
}
fflush(stdin);//使回车不被读取
}
}

void getInput0(void)//yangnan
{
int i=0;
char ch;

while(1){
ch=getchar();
switch(ch) {
case'I':
Call[i]=1;
break;
case'U':
Call[i]=2;
break;
case'Y':
Call[i]=3;
break;
case'T':
Call[i]=4;
break;
case'R':
Call[i]=5;
break;
case'E':
Call[i]=6;
break;
case'W':
Call[i]=7;
break;
case'Q':
Call[i]=8;
break;

case'K':
Call[i]=2;
break;
case'J':
Call[i]=3;
break;
case'H':
Call[i]=4;
break;
case'G':
Call[i]=5;
break;
case'F':
Call[i]=6;
break;
case'D':
Call[i]=7;
break;
case'S':
Call[i]=8;
break;
case'A':
Call[i]=9;
break;

case '1':
Call[i]=1;
break;
case '2':
Call[i]=2;
break;
case '3':
Call[i]=3;
break;
case '4':
Call[i]=4;
break;
case '5':
Call[i]=5;
break;
case '6':
Call[i]=6;
break;
case '7':
Call[i]=7;
break;
case '8':
Call[i]=8;
break;
case '9':
Call[i]=9;
break;
}
i++;
fflush(stdin);//使回车不被读取
}
}

void Uper(void)
{
int step;
for(step=1;step<=20;step++){
WaitFor(50);/*等待50毫秒*/
move(0.075);
}
}
void Downer(void)
{
int step;
for(step=1;step<=20;step++){
WaitFor(50);/*等待50毫秒*/
move(-0.075);
}
}

但是这个算法可能会有点小问题,你研究一下看看,多多少少有帮助的

4. 电梯调度算法...

不管你是在北上广还是在港澳台,甚至三四线城市,凡是有规模的地区,高楼比比皆是。不管是写字楼,还是大型商城,让你最头痛的就是乘电梯,尤其是在赶时间的时候。

每天早上,那些差5分钟就迟到的程序员,在等电梯时,一般会做两件事:

前者可能是写字楼里上班族惯有的精神类疾病,但后者肯定是程序员的职业病。本文对“骂电梯”不给予任何指导性建议。

但说起电梯调度算法,我觉得还是可以给大家科普一下,好为大家在等电梯之余,打发时间而做出一点贡献。

(电梯调度算法可以参考各种硬盘换道算法,下面内容整理自网络)

先来先服务(FCFS-First Come First Serve)算法,是一种随即服务算法,它不仅仅没有对寻找楼层进行优化,也没有实时性的特征,它是一种最简单的电梯调度算法。

它根据乘客请求乘坐电梯的先后次序进行调度。此算法的 优点是公平、简单,且每个乘客的请求都能依次地得到处理,不会出现某一乘客的请求长期得不到满足的情况

这种方法在载荷较轻松的环境下,性能尚可接受,但是在载荷较大的情况下,这种算法的性能就会严重下降,甚至恶化。

人们之所以研究这种在载荷较大的情况下几乎不可用的算法,有两个原因:

最短寻找楼层时间优先(SSTF-Shortest Seek Time First)算法,它注重电梯寻找楼层的优化。最短寻找楼层时间优先算法选择下一个服务对象的原则是 最短寻找楼层的时间。

这样请求队列中距当前能够最先到达的楼层的请求信号就是下一个服务对象。

在重载荷的情况下,最短寻找楼层时间优先算法的平均响应时间较短,但响应时间的方差较大 ,原因是队列中的某些请求可能长时间得不到响应,出现所谓的“ 饿死”现象

扫描算法(SCAN) 是一种按照楼层顺序依次服务请求,它让电梯在最底层和最顶层之间连续往返运行,在运行过程中响应处在于电梯运行方向相同的各楼层上的请求。

它进行寻找楼层的优化,效率比较高,但它是一个 非实时算法 。扫描算法较好地解决了电梯移动的问题,在这个算法中,每个电梯响应乘客请求使乘客获得服务的次序是由其发出请求的乘客的位置与当前电梯位置之间的距离来决定的。

所有的与电梯运行方向相同的乘客的请求在一次电向上运行或向下运行的过程中完成, 免去了电梯频繁的来回移动

扫描算法的平均响应时间比最短寻找楼层时间优先算法长,但是响应时间方差比最短寻找楼层时间优先算法小, 从统计学角度来讲,扫描算法要比最短寻找楼层时间优先算法稳定

LOOK 算法是扫描算法(SCAN)的一种改进。对LOOK算法而言,电梯同样在最底层和最顶层之间运行。

当 LOOK 算法发现电梯所移动的方向上不再有请求时立即改变运行方向 ,而扫描算法则需要移动到最底层或者最顶层时才改变运行方向。

SATF(Shortest Access Time First)算法与 SSTF 算法的思想类似,唯一的区别就是 SATF 算法将 SSTF 算法中的寻找楼层时间改成了访问时间。

这是因为电梯技术发展到今天,寻找楼层的时间已经有了很大地改进, 但是电梯的运行当中等待乘客上梯时间却不是人为可以控制

SATF 算法考虑到了电梯运行过程中乘客上梯时间的影响

最早截止期优先(EDF-Earliest Deadline First)调度算法是最简单的实时电梯调度算法,它的 缺点就是造成电梯任意地寻找楼层,导致极低的电梯吞吐率。

它与 FCFS 调度算法类似,EDF 算法是电梯实时调度算法中最简单的调度算法。 它响应请求队列中时限最早的请求,是其它实时电梯调度算法性能衡量的基准和特例。

SCAN-EDF 算法是 SCAN 算法和 EDF 算法相结合的产物。SCAN-EDF 算法先按照 EDF 算法选择请求列队中哪一个是下一个服务对象,而对于具有相同时限的请求,则按照 SCAN 算法服务每一个请求。它的效率取决于有相同 deadline 的数目,因而效率是有限的。

PI(Priority Inversion)算法将请求队列中的请求分成两个优先级,它首先保证高优先级队列中的请求得到及时响应,再搞优先级队列为空的情况下在相应地优先级队列中的请求。

FD-SCAN(Feasible Deadline SCAN)算法首先从请求队列中找出时限最早、从当前位置开始移动又可以买足其时限要求的请求,作为下一次 SCAN 的方向。

并在电梯所在楼层向该请求信号运行的过程中响应处在与电梯运行方向相同且电梯可以经过的请求信号。

这种算法忽略了用 SCAN 算法相应其它请求的开销,因此并不能确保服务对象时限最终得到满足。

以上两结介绍了几种简单的电梯调度算法。

但是并不是说目前电梯调度只发展到这个层次。目前电梯的控制技术已经进入了电梯群控的时代。

随着微机在电梯系统中的应用和人工智能技术的发展,智能群控技术得以迅速发展起来。

由此,电梯的群控方面陆续发展出了一批新方法,包括:基于专家系统的电梯群控方法、基于模糊逻辑的电梯群控方法、基于遗产算法的电梯群控方法、基于胜景网络的电梯群控方法和基于模糊神经网络的电梯群控方法。

本人设置的电梯的初始状态,是对住宅楼的电梯的设置。

(1)建筑共有21层,其中含有地下一层(地下一层为停车场)。
(2)建筑内部设有两部电梯,编号分别为A梯、B梯。
(3)电梯内部有23个按钮,其中包括开门按钮、关门按钮和楼层按钮,编号为-1,1,2,3,4……20。
(4)电梯外部含有两个按钮,即向上运行按钮和向下运行按钮。建筑顶层与地下一层例外,建筑顶层只设置有向下运行按钮,地下一层只设置有向上运行按钮。
(5)电梯开关门完成时间设定为1秒。电梯到达每层后上下人的时间设定为8秒。电梯从静止开始运行到下一层的时间设置为2秒,而运行中通过一层的时间为1秒。
(6)在凌晨2:00——4:30之间,如若没有请求信号,A梯自动停在14层,B梯自动停在6层。
(7)当电梯下到-1层后,如果没有请求信号,电梯自动回到1层。

每一架电梯都有一个编号,以方便监控与维修。每一架电梯都有一实时监控器,负责监控电梯上下,向电梯升降盒发送启动、制动、加速、减速、开关电梯门的信号。若电梯发生故障,还应向相应的电梯负责人发送求救信号。

电梯内部的楼层按钮:

这样就表示乘客将要去往此层,电梯将开往相应层。当电梯到达该层后,按钮恢复可以使用状态。

电梯内部开门按钮:

如若电梯到了乘客曾经按下的楼层,但是无乘客按开门按钮,电梯将自动在停稳后1秒后自动开门。

电梯内部关门按钮:

电梯外部向上按钮:

电梯外部向下按钮:

你肯能意识到 哪个算法都不是一个最佳方案,只是它确实解决了一定情况的问题 。但是对一个优秀的程序员而言,研究各种算法是无比快乐的。也许你下一次面试,就有关于调度算法的问题。

5. 如何将各种算法应用到实际的电梯调度中

说明 假设大厦有31层楼.电梯每经过1层(不论上下行)的时间是4秒.也就是说,电梯从1楼到31楼且中间不停则需要(31-1)*4=120秒.电梯每次需要停10秒,因此,如果电梯每层都停一次,就需要30*4+29*10=410秒.与此同时,员工步行一层楼(不论上下行)需要20秒,从1楼到31楼就需要30*20=600秒.明显,这个主意不好.因此,很多员工依赖电梯前往他们的办公室.现在我们需要设计一个方案,这个方案的设计目标是让最后一个到达办公室的员工花费最短的时间(也就是说,他并不保证每一位员工都能最快到达自己办公室).比如,如果员工想到达4,5和10层,则电梯的运行方案是在4和10层停止.因为电梯在第12秒到达4层,停止10秒,则电梯到达10层需要3*4+10+6*4=46秒.按此计划,住在4层的员工需要12秒,5层的员工需要12+20=32秒,10层的员工需要46秒.因此,最后到达办公室的员工需要46秒.对于大家来说,这是个不错的方案.

实现 下面就详细说一说我实现的具体方式,虽然花了我近2天的时间,但是其实并不是很复杂,这里我本着抛砖引玉的原则,下面就一起来看看吧:

我们将定义一个名叫Case的class用来存储一些要测试的数据,然后再定义一个叫CaseUtil的class用来实现我们的方案。

首先我说一下具体得思路:这里我只考虑从下到上的方案(从上到下其实是一样的,具体自己想吧)。举个例子,假设当前的楼层是【29 30 31】.3个。那么我们该如何做呢?

首先,不管怎么说,假设最后一层即31的到达时间为 (31-1)* 4 + (stopNums-1)*10 说明一下,这里为了简单起见我们就按照案例的数据进行分析,实际上4表示电梯经过每层所需时间,而10表示电梯每层停靠的时间。上面的stopNums是什么呢?就是电梯到达31层时所有的停靠次数,减去1是除去31层得停靠。而最后一层到达的人则很可能为最后一位到达的人,为什么不是一定呢,按照本例,上面举得例子就可以很简单的看出,在28、31停2次即可,此时最后一个到达的就是地30层的人了。当然在仅仅是在本例中,实际上会由于具体数值不一样而有不同。所以这里我用了可能,而它也和我们的最优解很接近了,而这给了我想法。虽然最后一层不一定是最后一位,但已经很接近了,而它所花费的时间,仅仅只和一个变量有关,即stopNums,即可以得出如下结论:

电梯的停靠次数越少,最后一层的时间也就越少,同样最佳时间也就越少。

假设我们有一个方法可以根据当前的停靠次数来计算最佳的停靠方案,那么我们该如何得到实际最佳方案呢?下面的一段代码很好的可以达到我们的目标。

阅读全文

与如何设计电梯算法相关的资料

热点内容
两个数字的加减乘除运算编程 浏览:221
给手机加密码忘记了怎么办 浏览:596
单片机运算符 浏览:292
移动端微信商城源码 浏览:442
编程猫下一个背景在哪里 浏览:356
javaclasstype 浏览:238
乐高编程和乐高课的延伸 浏览:354
苹果手机怎么切换app美国账号 浏览:865
编译程序输入一个字符串 浏览:407
圆命令画法 浏览:308
如果给电脑e盘文件加密 浏览:802
javaswing项目 浏览:778
androidsdksetup 浏览:1005
pdf怎么设置中文 浏览:128
安卓手机用什么软件看伦敦金 浏览:966
魅族文件夹无名称 浏览:792
苏黎世无人机算法 浏览:876
核桃编程和小码王的融资 浏览:686
微积分教材pdf 浏览:728
写python给微信好友发消息 浏览:340