清扫整个 Albert Heijn 超市的地面。听起来很简单。而且原本也应该很简单。

但我是一名计算机科学专业的学生,我遇到了一个问题:我总是忍不住去优化一些(可能)不需要优化的东西。

所以,我没有只是做好我的工作,比如扫地,而是做了任何一个“理智的”人都会做的事:我把超市的平面图转换成了网格图,构建了一个可视化编辑器,并使用模拟退火算法编写了一个 C++ 路径优化器。

但在我们深入探讨这件事是如何彻底出错,以及这件事如何让我意识到这会让每个人都痛苦之前,我需要你回答一个问题:

如果你要替我工作一天,并且需要打扫整个 Albert Heijn 超市的楼层,你会选择 A 路线还是 B 路线?
img
路径 A(上)和路径 B(下)。

说真的,看看它们。哪个看起来更适合清扫超市地面?

如果你选择了A选项:恭喜你,你的思维方式像算法一样,很可能就是个机器人。

但从技术上讲,你的说法没错。路径 A 的距离更短。然而,它完全没用。

看看那些弯道。你不妨想象一下,如果你走路时也这样弯,你会看起来像个疯子,就像一台抽搐的扫地机器人。

路径 A 是你优化了错误的东西而导致的结果。

剧透一下,这正是这个故事的重点。不过我们稍后再谈,先让我解释一下事情的来龙去脉:

第一步:将现实转化为过于简单的模型

首先,我把 Albert Heijn 的平面图转换成了网格。每个方格要么是空的(应该打扫),要么是障碍物(墙壁、收银台、有人扔在地上的酸奶包装)。

我在Processing中构建了一个可视化编辑器,这样我就可以轻松地绘制商店地图并导出生成的图表。

因此,将平面图转换为网格结构非常容易。
img
Albert Heijn 超市的网格平面图。

实际地面的瓷砖铺设有助于将该区域细分为易于管理的小块区域。
img
采用瓷砖结构的细分式平面图。

然后,通过将每个图块解释为一个节点,然后将它们连接到相邻的图块,就可以很容易地将其转换为网络结构(也称为图)。
img
将每个图块解释为图中的一个节点。
img
生成的瓦片网络。

如你所见,我允许水平和垂直移动,以及对角线移动(只要你不穿墙)。
img
Albert Heijn 的最终图表。

接下来唯一要做的就是找到一条贯穿这个网络的路径,同时确保访问所有节点(图块)。这样就能解决我的扫描问题。

(这个问题也称为旅行商问题,详情请参阅相关文章,了解它为何如此难以“解决”。)

第二步:编写优化器

由于在如此规模的图中,计算上不可能找到最优路径,我们只能求助于启发式算法。启发式算法本质上是在短时间内找到一个非常好的解,而不是试图找到完美的解(这几乎是不可能的)。

所以我用 C++ 实现了路径优化器。

底层启发式算法:模拟退火

如果你还不熟悉,模拟退火本质上就是尝试一系列微小的变化(也称为局部移动)。

一开始,你接受每一个小小的改变(即使它让路径变得更糟),但随着算法的进行,你会逐渐变得更加挑剔,最终只允许那些严格意义上改善路径的改变。

这个想法源于金属冷却的过程。首先,金属在高温下运行(尝试不同的运动方式)进行充分的探索,然后逐渐冷却,最终稳定在低能量状态(接近最佳状态)。
img
模拟退火算法通过多次迭代逐步改进路径。

看看这个动图。看到了吗?它一开始很混乱,然后逐渐变得稳定下来。这就是模拟退火算法的工作原理。

对于局部移动,我使用了 2-opt 移动。具体来说,就是移除路径中的两条边,然后用不同的方式重新连接它们。如果这种微小的改动使路径变得更好,就保留它。否则,要么保留它(如果温度仍然很高),要么舍弃它。
img
2-opt 移动可视化。

那就这么做十亿次。或者,让你的电脑这么做十亿次。

第三步:搞砸

运行一段时间后,我得到了第一条“优化”路径。以下是优化结果:
在这里插入图片描述

第一条“优化”路径。

瞧瞧这路!弯道比克里斯托弗·诺兰的电影还多。谁会傻到真的这么扫地啊?扫完估计都想吐。

从技术上讲,它覆盖了整个地面。从技术上讲,它(几乎)是最小的清扫路径。从技术上讲,它是完美的。

它有一些优点,但实际上,它完全没用。

算法完全按照我的要求执行了。

我问错问题了。

第四步:根据实际情况进行优化

我很快意识到我优化的方向错了。距离并非一切。

转弯很重要。动量很重要。看起来不像个故障的机器人也很重要。

所以我给成本函数增加了一个“转弯惩罚”,并要求它最小化这个惩罚。基本上就是告诉算法:“转弯90度会扣分。转弯180度?你疯了吧。”

这样一来,路线就更加顺畅了,即使距离略微延长了一些。
在这里插入图片描述

更平坦、更适合步行的道路。

你看,这其实……挺好走的。你把这条路交给一个真正的人,他也不会立刻放弃。

我们不再追求距离上的最优解,而是追求与现实的契合度。

第五步:打破它

接下来才是精彩的部分。

您可以调整急转弯的惩罚。这相当于一个滑块,可以在“纯粹的效率”和“实际用途”之间切换。
img
从低角度罚分(1)到高角度罚分(6)。

你可以清楚地看到其中的权衡。增加惩罚,路径会更平滑,但会稍长一些。减少惩罚,效率会提高,但会造成混乱。

选择哪条路完全取决于你自己。这取决于很多因素,比如你转身是否方便,总距离是否是首要考虑因素,以及你能忍受多大的眩晕。

第六步:意识到生活其实并没有那么美好

但这不仅仅是扫地那么简单。

这关乎一切。

社交媒体算法以提升用户参与度为目标,而且它们在这方面做得非常出色。问题出在哪里呢?

参与度≠幸福。参与度≠真相。参与度=点击量、屏幕使用时长、愤怒情绪和负面反应。

后果?愤怒、错误信息、负面新闻刷屏、焦虑。

算法运行完美,完全按照设计预期执行。问题出在成本函数上。(Instagram 可能不这么认为。)

推荐算法会优化观看时长和点击率。你奶奶正在YouTube上连续看6个小时的阴谋论视频。

算法彻底毁了她。她感觉糟透了。

这并不令人意外。

即使是像 ChatGPT 这样的大型语言模型,它们的优化方向也错了。它们优化的是听起来自信,听起来好像知道答案。

不是因为他正确,也不是因为他诚实。

他们接受的训练是完成既定模式,而不是说“我不知道”。所以他们只能靠猜测。而且毫无羞耻心,语法也完美无瑕。

这一点甚至适用于科技以外的领域。

想想企业。它们大多以盈利为目标。地球、环境、道德或伦理呢?这些都没有纳入成本函数,因此也不会被优化。

我在实际工作中是否使用了这条优化路径?

不,显然不是。我只是像正常人一样扫了地而已。

但构建这个项目教会了我一个我一直在思考的道理:如果你解决的是错误的问题,那么技术上的正确性就毫无意义。

你可以写出完美的代码,你可以构建完美无瑕的系统,你可以把成本函数优化到极致,但最终结果仍然可能很糟糕。

重要的不是优化算法本身,而是首先要弄清楚你究竟应该优化什么。

大多数时候,我们甚至都不会问这个问题。我们只是优化那些容易衡量的指标,然后祈祷结果会好起来。

https://tiespetersen.substack.com/p/i-got-paid-minimum-wage-to-solve

笔者公众号「深度涌现」

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐