一、SSTF算法实现
最短寻找楼层时间优先(SSTF-Shortest Seek Time First)算法的核心思想是寻找最近的乘客进行服务。而为了使电梯具有实用性,仅当电梯中无人时寻找最近的乘客,且不会被打断。在这个过程中如果有新的乘客等待,则上电梯,中断寻找。电梯内有人时按原运行方向运行,直到最后一个乘客下电梯。
当电梯到达楼层有乘客等待,乘客上下楼方向与电梯运行方向一致,而且当前电梯可以到达乘客目标楼层时开门,不然继续上、下楼。当该乘客为最高/最低层乘客时,开门,上电梯。其他情况均不开门。电梯没人时会自动检测最高楼层乘客和最低楼层乘客,电梯不会前往比最低楼层乘客所在楼更低处和比最高楼层乘客所在楼更高处。
SSTF算法的主要逻辑如下:
public void sstfDispatcher(){
随机生成乘客
调度电梯所用的线程(共4个)
for (int i = 0; i < ELE_COUNT; i++)
{
new Thread(()->{
while (true){
获取此刻状态和楼层
获取最近乘客(包括判断该乘客目标楼层是否可达)
如果电梯无人,改变电梯运行方向为前往最近乘客的方向
while(未到达最近乘客所在楼层且电梯无人){
如果在本层提供服务
检测有无人上下电梯
继续上/下楼
}
判断是否在本层服务
检测有无上下电梯
电梯运行
}
}
}).start();
}
}
其中,寻找最近乘客使用了EleController类中的getNearestPsg()函数,该函数可以寻找可以到达目标楼层的最近的乘客。
乘客进出电梯也封装成了一个函数psgOnOrOff(),先检测所到楼层是否有乘客,乘客目标楼层是否可达,且乘客目标方向与当前电梯运行方向是否一致,若都满足,则开门,乘客上电梯或下电梯。乘客上下电梯的实现与bus算法相同。
电梯运行分为两种,一种是eleRun(),另一种是eleSmartRun()。eleSmartRun()仅用在电梯无人时:若没有顾客等待,电梯暂停休眠一定时间;若当前楼层上行且未达所能达到的最高楼层和最高楼层乘客所在楼层,则继续上行,反之下行。另一种eleRun()按原方向一直运行,直到到达最高能到楼层或最后一个乘客下电梯。
二、LOOK算法
在实现SSTF算法时其实顺便就把LOOK算法实现了,不过SSTF算法并不一定比LOOK算法实用。
LOOK算法的思想是发现电梯所移动的方向上不再有请求时立即改变运行方向。在实现上,把上面的SSTF算法中的寻找最近乘客的部分去掉,就是LOOK算法了。主要靠eleSmartRun()实现。具体实现函数同SSTF算法。
public void lookDispatcher(){
随机生成乘客
调度电梯所用的线程(共4个)
for (int i = 0; i < ELE_COUNT; i++)
{
new Thread(()->{
while (true){
获取此刻状态和楼层
判断是否在本层服务
检测有无上下电梯
电梯运行(在这里判断电梯移动方向上是否有请求)
}
}
}).start();
}
}
三、算法与UI界面连接
ui界面使用的是javafx,共有三个界面:
Start
该界面的作用是实现同时打开多个电梯控制器窗口,即主窗口。点击中间的按钮即可打开一个新的电梯控制器窗口,每个窗口之间独立。
MainWindow
该界面为主界面,左上可以手动添加乘客,由onAddCosButtonClicked()实现。
然后按下旁边的Bus,SSTF,LOOK按钮分别执行对应算法。由于时间关系,并没有实现算法切换和暂停等功能。
接着左边”等待人数“,”服务人数“,还有下面”总人数“分别对应当前等待上电梯的人数,服务过的人数,以及开始到运行时总的人数。”服务人数/总人数“是对电梯运行效率的评价指标,初始值为1,由refreshTotalInfo()方法实现。
左边的白色TextArea用来显示所有乘客的信息,由refreshHisCosInfoArea实现。
右边四个电梯的情况从上到下进行说明:
上面部分实时显示电梯当前到达楼层,由changeFloor()方法实现。
中间人数和剩余可容纳重量由setEleInfo()方法实现。
下面更新上过电梯的乘客信息由refreshEleArea()方法实现。
点击最右边设置电梯参数按钮会弹出新的窗口,以改变电梯参数,具体如下。
SetElePara
填好电梯参数后点击修改参数就可以修改特定电梯的参数。由onSetButtonClicked()方法实现。