电梯里没有按钮,反而更慢?

电梯里没有按钮,反而更慢?

algorithmelevator科普

数据源:HN + web research · HN

昨天,一篇讲电梯怎么走路的科普文章,登上了全球最大程序员社区的头名——771 个赞,198 条评论。程序员们为一部电梯吵了一整天。

话题的起点是个反常识的结论:一些新写字楼把电梯里的楼层按钮搬到了大堂,让你进电梯前先选好去哪层,系统再给你分配电梯。这套叫「目的地派梯」的系统,在多数模拟场景里,竟然比老式的上下按钮更慢。评论区里有电梯工程师、有写磁盘驱动的、有管酒店物业的,各说各话。

电梯是每个人每天都用的东西,背后的门道却少有人知道。这篇文章用交互式模拟把这件事讲清楚了:每种算法都配了可以调速的动画,读者能自己加楼层、加电梯,亲眼看着不同算法的等待时间分布发生变化。评论区又补上了不少真实世界的细节。笔者把它整理出来,给不写代码的朋友们看看。

电梯调度难在哪

先看物理规律。一部电梯同时只能朝一个方向走;载客量有限;楼层越高,选择越多。多部电梯一起运行时,谁去接谁、按什么顺序停,就成了调度问题。

客流还不对称。写字楼早高峰,几乎所有人都从大堂去高层;晚高峰反过来,全往下走;午间则是混合的。同一套规则,在不同时段表现天差地别。早高峰的等待统计往往最难看的。

还有一层麻烦:写字楼的电梯通常是一组共用一个按钮面板,五六部轿厢共享同一批呼叫。你按了上行,系统要决定派哪一部来接你。这个决定每时每刻都在重做,轿厢在动、人在进、请求在变。调度难就难在这里——一部电梯的规则简单,一群电梯的协调复杂。

老式电梯怎么工作

最常见的算法叫 SCAN,1961 年就有专利:电梯从大厅一路开到顶楼,再掉头下来,沿途有人就停。就像一趟公交车,顺路捎带。这也是很多老楼里电梯的实际走法。它还有个更直白的名字——「电梯算法」,因为计算机科学家发现磁盘磁头的移动方式和电梯一模一样,干脆借用了这个名字。

大部分时候你不需要到顶楼。于是有了改进版 LOOK:开到当前方向上最远的请求楼层就掉头。这是大多数人熟悉的行为——电梯在一个方向上走到底,中间有人按就停。两个算法都遵循同一条朴素的规则:保持方向,顺路捎带,到头再回头。

电梯模拟演示 图:John.fun 交互式科普的电梯模拟演示。来源:john.fun/elevators

衡量电梯好不好,标准是等待时间。严格一点要看分布:p50 是一半的人要等多久,p90 是九成的人等多久。平均等待时间没几个人记得住,人们记住的是那几次「等了仿佛一个世纪」的时刻。算法优化的目标,常常就是压住 p90。

等待时间分布演示 图:John.fun 交互式科普的等待时间分布演示。来源:john.fun/elevators

这里还有一组对抗:等得短,未必坐得短。电梯为了顺路捎带更多人,会频繁停站,你在轿厢里的时间就变长。等待时间和乘坐时间,优化一个往往牺牲另一个。调度算法做的,就是在两者之间找平衡。

更聪明,不一定更好

多部电梯时,基础的做法是中央调度:新请求来了,派给最近的电梯。工程师们不满足于此。奥的斯有一款 RSR 算法,给每部电梯打分:接到你的预计时间、当前载客量、是否与别的电梯扎堆、是否顺路、附近有没有空车……分数低的电梯去接你。这套系统每 5 秒重新优化一次,电梯 A 迟到了,任务可能转给电梯 B。

RSR 里有一条反扎堆规则:另一部电梯已经奔着同一楼层去了,这部就不去凑热闹。写字楼里两部电梯同时开门迎接你的场面,就是反扎堆没做好的结果。打分是实时的,轿厢每动一步,各家的分数就变一次。

模拟结果却有点打脸:流量越高,简单的 LOOK 反而越跑赢复杂的 RSR。小楼、电梯少的场景里,LOOK 也常胜出。规则越多未必越快,有时候保持简单是对的。这对工程是个提醒:算法复杂度和性能提升之间,隔着具体场景。

新式电梯的争议

目的地派梯(Destination Dispatch)的逻辑是:既然系统提前知道每个人去哪层,就能把去同一层的人塞进同一部电梯,减少停站。信息更全,理论上应该更优。酒店、医院、超高层写字楼里,这种 kiosk 已经不少见。

文章的模拟给出了相反的结论:多数情况下,派梯比传统的上下按钮更慢。原因在灵活性。传统电梯每 5 秒可以重新优化路径;派梯则把乘客锁死在指定的电梯里——你按了楼层,就必须上那部。30 秒后世界可能完全变了,系统却改不了口。额外的信息,抵不上损失的灵活性。

评论区对此提出了反驳。有工程师指出,真实写字楼的午餐时段,是一大群人同时去同一层吃饭,派梯恰好擅长这种批处理;酒店的早高峰双向客流,kiosk 界面也会专门切到早餐模式。模拟里没覆盖这些模式,结论自然偏向老算法。双方说的都有道理:派梯的优劣,取决于客流长什么样。它仍是不少新地标建筑的选择,但「新的一定更快」这句话站不住。

目的地派梯演示 图:John.fun 交互式科普的目的地派梯演示。来源:john.fun/elevators

硬盘是一台卷起来的电梯

评论区还有一个让笔者眼前一亮的细节:SCAN 算法,就是计算机硬盘的磁头调度算法。维基百科上它有两个名字:「电梯算法」和 SCAN。它最早就是用来调度磁盘读写请求的。

磁盘里,磁头要在盘片上寻道读取数据,就像电梯在楼层间接送乘客。读写请求分布在盘面各处,磁头顺着一个方向扫过去,沿途处理请求,到头再反向扫回来,和电梯一模一样。机械硬盘的寻道是整台机器里最慢的动作之一,调度省下的正是这段机械时间。有程序员调侃:硬盘就是一台卷起来的电梯。

计算机科学教材里,SCAN 是磁盘调度的经典章节;电梯公司 1961 年的专利,和操作系统教科书,用的是同一套思路。高德纳在《计算机程序设计艺术》里讨论协同程序时,举的例子就是模拟一部电梯。一个载人,一个载数据,调度逻辑相通。

这套算法如今在硬盘里慢慢退休了——固态硬盘寻道时间趋近于零,顺序读取的收益不再明显。电梯里它还在天天上班。同一套思路,从 1961 年的专利一路走到今天的电梯控制系统,横跨了机械工程和计算机科学两个领域。

结尾

电梯听到了你的呼叫,它只是要想的事情很多。下次等电梯等到怀疑人生时,不妨想想:你按下的每一个按钮背后,都有一群工程师在争论怎么让算法更快——而有些争论,到现在还没有定论。

参考链接:

  • John.fun:Elevators 交互式科普
  • HN 讨论 (item?id=49124218)