最近突然想到一个问题,如果我在每一步都选择了当时最好的选项,那么这些选择最后加起来,不就应该得到一个最好的结果吗?

“局部最优不等于全局最优”,这句话我当然知道。但是知道归知道,仔细想想,还是觉得有点奇怪。假如每一次选择都没有选错,最后怎么会走到一个并不那么好的地方呢?反过来说,假如最后的结果不好,那么到底是哪一步出了问题?

拿爬山来想,这件事倒是很容易理解。每一步都朝着上升最快的方向走,最后可能只会走到附近一座小山的山顶。到了那里,周围都是下坡,看起来已经没有更好的路了,但是远处还有一座更高的山。想去那里,就得先下山。

所以只看下一步,向下走确实是一个更差的选择;但是把后面的路也算进去,它又可能通向一个更好的结果。这其实不难懂。学习、转行、放弃一个还不错的机会,好像都可以套进这个解释里面。但是这样一来,又很容易说出一些听起来很有道理、实际上没什么用的话,比如“不要只看眼前,要有长远眼光”。

问题是,我当然也想有长远眼光,可我又不知道远处到底有没有那座更高的山。

如果我已经知道下山之后能够走到哪里,那倒简单了。可现实中,我可能下了山,走了很久,最后发现那里还不如原来的地方。难道只要眼前吃了亏,就一定是在为将来的好结果做准备吗?当然不是。局部最优未必能得到全局最优,局部更差也没有什么天然的优越性。

想到这里,我反而觉得,对每个人来说,好像本来就只能选择某种“局部最优”。我可以想今晚,可以想三个月以后,也可以想三年以后,但无论想得多远,终究都只是我此时此刻对未来的一点预测。把视野从今晚拉到三年,也只是把这个“局部”放大了一些,我又没有因此知道第四年会发生什么。

不过严格一点说,这里的“局部”和数学里说的局部最优已经不是同一个意思了。数学里的局部最优,是在某个解的附近找不到更好的解;我这里想说的,其实是信息和时间范围都有限,只能在自己目前能够想到的那些可能性里面做选择。甚至连这个范围内的最好,我也未必找得到。

这么一想,“站在全局看问题”就变得有点奢侈。所谓全局在哪里呢,谁能够站在那里?

说到这里我想起了贪心算法。既然每一步选择当前最好的,并不一定能得到最好的结果,那么贪心算法到底是在做什么?它不就是每一步都选当前最好的那个吗?难道它也只是找一条看起来还不错的路,最后好不好,仍然要看运气?

这里有一个我之前没有想得很清楚的地方。贪心是一种选择方式,但某种贪心规则能不能求出全局最优,需要证明。对于那些能够证明正确的贪心算法,它确实可以只走一条路,就得到全局最优解。它敢把其他可能性放掉,是因为问题本身有这样的性质。

最容易理解的例子是安排会议。假如只有一个会议室,所有会议的开始和结束时间都已经知道,目标也很简单,就是尽可能多地安排互不冲突的会议。那么可以每次选择当前还能安排、并且结束时间最早的那个。

直觉上很好理解,结束得早,后面就能留出更多时间。但是直觉好像还不够,凭什么这个规则一定成立呢?

可以先假设已经有一个安排了最多会议的方案,它的第一场会议叫 X,而所有会议里面结束最早的那场叫 A。如果这个最优方案没有选 A,就把 X 换成 A。因为 A 结束得不比 X 晚,原来能排在 X 后面的会议,现在仍然可以排在 A 后面,会议的总数也没有减少。

这样一换,我们就得到了一个以 A 开头的最优方案。这叫交换论证。

我觉得这里最有意思的是,我们根本不需要先找出那个最优方案长什么样,也不需要证明所有最优方案都一定选 A。只要能够证明,至少有一个最优方案可以选 A,这一步就可以定下来了。选了它以后,通往最优结果的路仍然存在。

接下来,只看 A 结束之后还能安排的会议,又变成了一个更小的同类问题。剩下的部分也必须安排得最多,否则把它换成更好的安排,原来的方案就不能叫最优了。这就是所谓最优子结构。然后再选结束最早的,再做一次相同的论证,一直重复,直到没有会议可选。

听起来其实就是一个递归的过程。当然代码完全可以写成循环,只是它背后的证明是一层一层缩下去的。动态规划也会把问题拆小,不过通常还需要比较不同选择对应的结果,再把重复的子问题复用起来。这里的贪心则能够提前证明一个选择是安全的,于是其他分支就不用继续算了。

到这里我才觉得,贪心算法的关键大概在于那个证明。有了证明,才可以放心地不回头。连上面这个会议问题,如果目标换成让会议的总收益最高,而每场会议的收益又不一样,原来的证明就不够用了。换成结束更早的会议,数量虽然没少,收益却可能少了。规则看起来还是那个规则,能不能用,却取决于我们到底在求什么。

然后我又想到了人生。如果把那个能够安全确定下来的选择叫作 g,那么人生里面,会不会也有一些这样的 g 呢?不需要知道最终会过成什么样,只要先选了它,至少不会把一个更好的结果排除掉。

比如学习一点有用的东西,照顾好身体,维护重要的关系。这些事听起来总归是好的吧?即便不知道未来,先做这些,好像也不会有什么错。想到这里,我自己又觉得不太对。做每件事,至少在时间上都是有机会成本的。

学一门东西当然可能有用,可是假如它需要一百个小时,这一百个小时原本也可以用来做项目、找工作、陪伴家人,或者只是好好休息。不能因为学完之后比没学之前多懂了一点,就说明这段时间用得最好。“这件事有好处”和“此时应该选择这件事”,中间其实还隔着很多东西。

所以要在人生里面找到一个严格意义上的 g,似乎远比想象中困难。我要知道它本身带来的好处,还要知道为了做它放弃了什么,以及这些放弃会怎样影响后面的生活。可我连未来有哪些会议都不知道,更不用说它们什么时候结束、各自又值多少了。

而且会议的目标是固定的,数量越多越好。人生却连这一点都未必有。我现在觉得重要的东西,过几年可能没有那么重要了;我现在愿意放弃的东西,以后也可能恰恰是我最想要的。选择会改变生活,生活又会改变做选择的那个人。拿现在的标准去算一辈子的最优结果,总感觉哪里不太对。

这也让我觉得,回头评价以前的选择时,或许应该稍微小心一点。一个选择最后没有得到好结果,并不能单凭这一点就认定,当初做这个选择是错的。假如当时已经认真考虑了能够获得的信息,后来却发生了预料不到的变化,那么拿后来的答案要求当时的自己,好像并不公平。

当然,这也不能成为一句万能的安慰。有些事情当时确实不知道,有些事情却是当时已经看见了,只是不愿意承认,或者觉得以后再说。后者还是值得反思的。只是反思的时候,应该尽量分清楚,我到底是在责怪自己当时没有认真想,还是在责怪自己没有提前知道未来。

想了这么多,好像还是没有找到一个选了就一定不会错的选项。但如果稍微放松一点要求,事情又没有那么绝望。

有些东西确实在很多种未来里都用得上。比如学习和表达的能力,一点能够让生活不那么窘迫的积蓄,身体还能够支持自己做想做的事。这些当然也有成本,也不能不计代价地投入,只是相较于把所有希望都押在某一个预测上,它们对那个预测是否准确,没有那么依赖。

还有一些选择,会让以后有机会重新选择。今天多了解一点信息,明天就可能发现原来没有想到的方向;现在积累一点能力,以后想换一条路的时候,就不至于完全走不动。它们的价值有一部分要到以后才能看出来,甚至只有在我发现自己判断错了的时候,才会知道它们有多重要。

当然,保留选择也不意味着永远不选。一直等,等到所有信息都齐了,等到确定不会后悔了再开始,这种事大概是等不到的。就算什么都不做,时间也还是过去了,原本存在的机会也可能没有了。休息有休息的价值,等待也可能有等待的理由,只是它们同样要被算进选择里面。

写到这里,我又想起之前写打翻的牛奶时,那个想要提前看看人生结局的念头。那时候想知道后面会发生什么,现在想知道每一步究竟应该怎么选,似乎还是同一种心情。要是能提前确认一切就好了,要是有一个证明,告诉我这样选下去不会错就好了。

可惜目前还没有找到这样的证明。

我大概还是会想得远一点,也还是会后悔一些选择。只是下次再站在一个路口,或许可以少问自己一句“这是不是一辈子最好的选择”,先想想,按照现在知道的事情,我为什么愿意这样选,为了它要放弃什么,以及如果以后想法变了,还有没有调整的余地。

至于它最后是不是全局最优,我不知道。也许走到很后面,仍然不知道,毕竟那些没有选过的路,我也没有真的走过。

但下一步总还是要选的。