你等的电梯总不来?背后是一道数学题

你等的电梯总不来?背后是一道数学题

algorithmselevatorsdaily-life

数据源:Lobsters + web research

你按下电梯按钮,看着楼层数字一格一格跳。你以为这是运气问题——其实这是一道被研究了一百多年的数学题。

昨天(8月1日),网页开发者 John Allsopp 做的一个交互式电梯科普在技术社区 Hacker News 登顶,今天在 Lobsters 上继续被讨论(52 个赞、6 条评论)。它没有讲什么惊天动地的新闻,只是把电梯调度做成了可以亲手拖拽的模拟器。能火,大概是因为它回答了一个每个人都问过的问题:我按了按钮,电梯到底听见没有?

听见了。它只是要想很多。

电梯在优化什么:平均值会骗人

先看一个问题:怎么衡量一部电梯调度得好不好?

直觉答案是「平均等待时间」。但把成千上万次乘坐的等待时间画成分布图,平均值会骗人。John 的模拟给出了两个数:p50 是 1 分钟,也就是一半的人能在 1 分钟内上电梯;p90 是 2 分钟,也就是 90% 的人等待不超过 2 分钟。

p50 和 p90 之间差的这一分钟,藏着电梯行业的全部秘密:人脑不记平均,只记最惨的那一次。那 10% 的漫长等待,会在记忆里占据远超它份额的位置。所以「电梯总是不来」的感觉,很大程度是统计分布和大脑共同制造的错觉——你的电梯其实一半时候 1 分钟就到。

工程上的取舍也更复杂:平均等待、最长等待、能耗,三个目标互相打架。把电梯都派去接最近的人,平均等待最短,但极端情况下有人要等 5 分钟;牺牲一点平均,换掉「永远等不来」的极端值,是很多写字楼的实际选择。没有免费的午餐,电梯公司只是选了你想不到的那份菜单。

等待时间分布演示:p50 约 1 分钟,p90 约 2 分钟 图:原文用上千次模拟绘出的等待时间分布演示。来源:john.fun

最老的规则:一条道走到黑,再回头

在算法出现之前,电梯里其实坐着一个人。「电梯司机」这个职业直到二十世纪中叶还很常见:帮你开门、问你到几楼、手动开向目的地。后来电梯自动化,司机消失,规则交给机器,调度问题才从「人」变成「数学」。

最早的自动规则简单得惊人。1961 年获得专利的 SCAN 算法:电梯从大堂出发,一路向上,沿途捎上捎下,直到顶层再掉头向下,重复这个过程。后来有人觉得没必要每次都跑到顶,于是有了改进版 LOOK:只开到「还有人要去的最高层」就掉头。这套规则如今大多数人早已默认,甚至不会意识到它是「算法」。

它还有个有趣的亲戚:硬盘读写头的调度。磁盘磁头在盘片上找数据,走法几乎一样,计算机科学干脆把这套算法直接命名为「电梯算法」。一个 60 多年前的专利,今天还在你的硬盘和电梯里同时运行——简单规则的寿命,比大多数软件都长。

但单部电梯的规则解决不了早高峰。设想一栋写字楼:早上 9 点,几百人同时在大堂按上行键,系统如果傻乎乎地把每部电梯都派到大堂,就会出现三辆车同时开门、然后一起空着上楼的场面。调度器必须做一些「看起来不合理」的事:让一部明明空着的电梯绕路去接另一头的乘客。你站在 15 楼按了按钮,电梯却从你面前呼啸而过——它听见了,只是正在执行一个比你更大的计划。

一部电梯在四层小楼里往返的交互演示 图:原文首页的交互演示——一部电梯在四层小楼里往返,可以调快 25 倍观看。来源:john.fun

多部电梯的分工:每 5 秒重新打分

电梯多起来之后,问题才真正变难:谁来接谁?

现代电梯群控系统(比如奥的斯的 RSR 算法)的做法是打分制:给每部电梯算一个「接单分」,包含预计到达时间、当前载客量、会不会和别的电梯扎堆、是否顺路、是否正好空闲在附近,分数最低的电梯去接你。打分制的精妙之处在于它会反悔:每 5 秒重新计算一次,如果你的电梯在路上被堵住,你的单子可能被转手给另一部电梯。

John 的模拟给出了一个反直觉的结论:客流越大,简单的 LOOK 规则反而开始赢过复杂的 RSR;小楼、电梯少的时候,也是简单规则更好。「有时候保持简单更好」——这句大白话,是笔者读完全文后觉得最值钱的一句话。

智能派梯:信息更多,反而更慢

这几年高端写字楼流行一种新玩法:进电梯前,先在大堂的屏幕上选你要去的楼层,屏幕告诉你「请等 3 号梯」。这叫目的楼层派梯。听起来更智能:系统在你进电梯之前就知道所有人要去哪,当然能安排得更好?

模拟结果恰恰相反:在绝大多数场景下,这种派梯系统的平均等待时间,比老式的「上下按钮」更差。唯一能赢的场景,是超高层建筑里 8 部以上电梯组成的一组。原因是:老式系统每 5 秒重新优化的灵活性,被屏幕的「你必须上指定电梯」给锁死了。你按下楼层 30 秒后,整栋楼的局面可能已经变了,系统却没法反悔。

智能派梯(目的楼层派梯)交互演示 图:原文的智能派梯(destination dispatch)交互演示。来源:john.fun

Lobsters 上的工程师们贡献了现实版吐槽。一位叫 vbernat 的网友说,派梯系统要求每个人都老老实实去屏幕上选楼层,系统才知道该派多大的轿厢——总有人等急了再按一次,同一层就来了两部电梯。mitsuhiko(Flask 框架作者)补刀:这种系统在现实中,上错电梯、错过电梯的情况不少见。也有体验好的:配合门禁卡,刷卡瞬间就告诉你上哪部电梯,早高峰几秒就到;但代价是下行要等好几分钟——因为系统把全部力气都用在了保写字楼最疼的早高峰上。

这里有个值得停下来想的点:让系统知道更多信息,不等于它能把信息用好;系统的全局最优,常常和你的「电梯先来我这层」直接冲突。你个人的一分钟,和整栋楼几百人的一分钟,在调度器眼里不是一个东西。

为什么你总觉得慢:等待的心理学

最后说个冷知识:电梯公司很早就在研究「感知等待」。心理学发现,人等待时越无聊,时间过得越慢。经典做法是在电梯口放大镜子——有写字楼经理采纳过这个建议,效果据说不错。你等电梯时的焦躁,一半是算法给的,一半是大脑自己加的。

还有一个让人百思不解的现象:电梯上行下行次数一样多,为什么你总觉得它先往反方向走?答案的一部分在高峰期:满员的电梯经过你的楼层,装不下了,直接跳过去。你的大脑记住的,永远是那几台呼啸而过的满员电梯。

回到开头的问题:电梯听见你的按钮了吗?听见了。它只是要想很多——把几百人的目的地、载客量、能耗和「别让任何人等太久」放在一起,每 5 秒重算一次。下次等电梯时,如果它先去了别处,不妨把它想成一个正在做全局优化的调度器:它的账本上,有你的一分钟,也有整栋楼几百人的一分钟。

参考链接:

  • John Allsopp:Elevators(交互式科普)
  • Lobsters 讨论 (s/jxqf1w/elevators)
  • Wikipedia:Elevator algorithm
  • Signal v. Noise:Defining the problem of elevator waiting times
  • Scientific American:The reason why elevators feel slow