无聊之作:简单模拟电梯程序[Java]

记得刚开始学Java时用的是《Java大学教程》,这本书每章都在介绍一点电梯程序的样子,加上上班天天都要坐电梯,突发奇想想要做一个模拟电梯程序。

一开始没想清楚电梯程序的运行方式,但是知道几个关键表现。

  • 电梯有静止的时候
  • 电梯往往停在最后请求的楼层,也有最后静止在底层(1楼)的,这相当于电梯在没有请求时自己按了一下1
  • 电梯存在插队现象,即电梯在1楼,A在8楼先按,B在4楼后按,如果电梯没到4楼的话,后按的人先进

其实还有一个关键点,一般电梯都是有向上向下提示的,电梯上行时,A在8楼按下,B在4楼按下的话,B是不会插队的。不过如果把这个也考虑在内的话问题会复杂很多,因为操作电梯会有两步:指示方向和指出具体楼层。为了简化问题,我实际考虑每个楼层只有一个按钮,不指示方向,电梯内仍旧有具体到达楼层的按钮。这样的电梯可能有点怪,但也可以用。

电梯问题的重点个人认为在两块地方,一块是接受指令时,第二块是每层楼运行时。
能够想见,接受指令时决定了目标楼层(nextFloor),最简单的情况,电梯一开始就是静止的,那么第一次指令就决定了目标楼层。插队现象也不难理解,如果电梯的当前楼层和目标楼层中间出现了请求,那么电梯的目标楼层就变成了中间这层的请求。考虑到电机运行速度,可能要计算当前楼层加一或者加二以上的范围,否则就可能有安全问题。
每层楼运行时,如果没有新请求,那么电梯会往一个方向(direction)运行,比如上行(up),下行(down),直到抵达目标楼层。抵达之后的操作就是根据现在的方向寻找下一个目标楼层。比如现在上行,到达4层,现在6层有新请求,3层也有请求。那么电梯会往6层去,直到抵达最高层或者上层再没有新请求,再往下走。下行的话正好相反,先往下找请求,直到底层或者没有再往上找。
一句话来说,电梯的核心算法就是如何动态确定下一个目标楼层。

这个算法刚才其实已经差不多说得差不多了。然后是具体需要的参数,个人认为当前楼层(currentFloor),目标楼层(nextFloor),请求楼层(requests,一个BitSet,位集合),方向(direction),状态(status)就差不多了。以下是模拟代码:

实际执行结果如下:

感觉和实际电梯有点像,就是没有动画演示。
如果每个楼层的按钮有方向的话,其实重点改造位置还是在findNextRequestFloor,以及在receiveRequest的操作,数据结构上原先的requests(BitSet)可能不够,要分成上行请求/下行请求等。具体这里就不实现了。