3 部电梯 20 层楼,FCFS 换 LOOK 调度实测能快多少?
结论先说:8 组随机乘客流跑下来,LOOK 顺路扫描的平均等待比 FCFS 先到先服务少 17%~19%,总运行楼层少 16%~22%。
代价在尾部。0.06 人/秒这档客流里,LOOK 的 95% 分位是 102.1s,FCFS 只有 75.2s。

为什么盯上电梯
早高峰等电梯,我在写字楼大堂数过一次:3 部梯,20 层,等了 4 分钟才挤上去。
电梯不是没动,是一直在来回跑。
这套逻辑和操作系统里的磁盘调度是同一件事。磁头怎么走,电梯就怎么停,FCFS 和 LOOK 是最小的两个对照组。

两种规则,差别只在顺不顺路
FCFS 是谁先按谁先走。空闲的梯直奔请求层,接上人再去目的层,一趟只服务一个请求。
LOOK 是请求一到就派给最合适的梯子。梯子朝一个方向走,沿途有停靠就停,走到头再掉头。
单看文字,LOOK 显然更省。真实差距要看乘客怎么来。
实验参数
| 项 | 取值 |
|---|---|
| 楼层 | 20 层 |
| 电梯 | 3 部,单梯 8 人 |
| 层间耗时 | 2 秒 |
| 每次停靠 | 6 秒 |
| 乘客来源 | 泊松到达,随机层去随机层 |
| 观测窗口 | 15 分钟 |
乘客不会去同一层,也不会重复上同一部梯。引擎是一个 JS 文件,页面和命令行共用,种子固定,跑两次结果完全一样。
8 组种子,4 档客流
| 到达速率 | 乘客数 | FCFS 平均 | LOOK 平均 | 平均少等 | FCFS 95% | LOOK 95% | FCFS 楼层 | LOOK 楼层 |
|---|---|---|---|---|---|---|---|---|
| 0.02 | 17 | 21.5s | 16.6s | 23.0% | 40.7s | 40.8s | 233 | 186 |
| 0.03 | 27 | 23.6s | 19.5s | 17.3% | 42.3s | 48.7s | 393 | 308 |
| 0.05 | 44 | 29.0s | 23.5s | 19.2% | 58.2s | 63.0s | 623 | 504 |
| 0.06 | 51 | 40.2s | 33.1s | 17.7% | 75.2s | 102.1s | 713 | 594 |
0.02 那档只有 17 个人,LOOK 少等 23%,楼层少 20%,95% 分位几乎打平。
客流涨到 0.05,44 个人,平均少等 19.2%,楼层从 623 降到 504。
再看 0.06。平均 40.2s 对 33.1s,还是 LOOK 赢,可 95% 分位翻了过来,75.2s 对 102.1s,差 27 秒。

为什么尾部会变差
LOOK 让车一直朝一个方向走,站在这条线后面的人要等整轮扫完。
FCFS 是谁先按谁先走,单个请求的等待有上限。人多时它整体慢,但没人被压到最后。
我单独看了 0.06 这档的最长等待:FCFS 92.4s,LOOK 376.6s。这两个数字在页面上复算过两次,不是单次跑出来的偶然值。
低客流时结论会缩水
0.03 这档 27 人,平均少等 17.3%,楼层少 21.6%,95% 分位却从 42.3s 涨到 48.7s。
人越少,两种规则的差距越小。0.02 那档 95% 分位只差 0.1 秒。
所以别把「LOOK 快 19%」当成固定收益。它依赖客流密度。

踩坑:第一版接走了还没到的人
第一版引擎里,车一停就扫同层所有乘客,不看到达时间。
结果等待时间出现负数,最低 -58.1s。
根因不复杂:乘客列表是提前生成的,车把 10 分钟后才到的人也接走了。
第二版加了到达时间判断,负数消失,但还剩 25 人没送达。
追下去是满载问题。8 人满的梯子开到接人层,停 6 秒,一个人上不来,请求就挂在这部梯名下。
改成满员时把该层乘客退回待派队列,重新分给别的梯子,未送达归零。
页面自检
5 项断言全部通过:等待不为负、乘客全部送达、同批乘客对比、LOOK 楼层更少、同种子可复现。
自检和 8 组种子的明细在同一页,刷新后可以自己复核。

这套模拟管不到的事
真实电梯有分区、有群控、有早高峰上行优先,我这里全没做。
乘客也只按随机层走,没有「上班全去高层」的潮汐。
所以这些数字只能回答「两种规则谁平均更快」,不能直接拿去给真实楼宇选型。
自己跑一遍
打开 index.html,拖到达速率滑块,点重新模拟。三档客流下平均等待、95% 分位、总楼层都会重算。
源码两个文件:engine.js 是调度引擎,index.html 是界面。想改策略,动 assignLook 里那几行成本函数就行。
最后一句,电梯调度没有全能解。想要平均快,选 LOOK;想让人人有上限,FCFS 更稳。
- 点赞
- 收藏
- 关注作者
评论(0)