一些故事
波利亚在他著名的《How To Solve It》中讲了这么一个有趣的心理学实验:
用一个缺了一条边的正方形围栏围住一只动物(狗、黑猩猩、母鸡、人类婴儿),在围栏的另一侧放上一个被试很想要的物体(对动物来说是食物,对人类婴儿来说是有趣的玩具),然后观察他们各自的行为。发现,狗在扒着围栏吠了几声发现无法通过的时候,不久便学会了从围栏的缺口的那一边绕出去,母鸡则朝着围栏一个劲的扑腾,不会想到绕弯子。此外,人类婴儿很快就学会了绕过障碍;而黑猩猩也学得很快(黑猩猩是和人类最近的灵长类亲属)。这个实验有力的证明了,动物解决问题的能力是进化而来的、天生的、硬编码在大脑的神经元网络里面的。
事实上,不仅解决问题方面是如此,人类整个认知系统中绝大部分功能从本质上都是硬编码的,能在后天习得的只是“程度”的不同,而不是“本质”的不同。《动机心理学》中有一个令人印象深刻的一个例子:
先给小鼠喝某种甜味水(称为“可口水”),然后用X射线促使其产生反胃感,能使小鼠形成对这种味道的水的厌恶和回避(经典条件反射)。但如果不是在水里面加味道,而是在它喝水的时候伴随强光刺激(即让它喝“光噪水”),然后同样刺激其反胃,却无法使它养成对“光噪水”的厌恶。另一方面,如果不是促使其反胃(身体不适),而是用电击惩罚,则它无法形成对“可口水”的厌恶,而是形成对“光噪水“的厌恶。显然,小鼠对事件之间的关联的归因也具有着某种硬编码好了的倾向。在这个例子中,老鼠的大脑里面硬编码了“将身体不适(内部事件)归因于食物而不是闪光”、”将电击(外部事件)归因于闪光而非食物” 这种逻辑。
《像外行一样思考,像专家一样实践》中也提到,他认为人类的直觉实际上也是计算,捷径式的计算,只不过由于我们目前还不了解人类大脑内神经元的全部结构(或者说“感性”的物质基础)这才把“感性”当成人类所特有的;金出武雄的这种观点跟心理学中的认知捷径不谋而合。实际上,越是高等的动物,大脑中用于处理特定问题的硬编码神经元回路就越是多和复杂。例如,达尔文早在《人类和动物的情绪表达》中就先知先觉的提出了动物情绪的适应价值;《Mean Genes》列出了用于解决生存繁衍问题的特定认知倾向;《决策与判断》里面则列出了人类在解决更具一般性的决策问题中的一些系统性的、可预测的认知偏差;而《Predictably Irrational》更是把这个认识提高到方法论的层面,主张人类的非理性实际上是完全可预知的。事实上,所有这些观点都建立在一个基本事实的基础上,即人类大脑中的千亿神经元是由在漫长的进化过程中被塑造出来的分工明确的、ad hoc的一组子系统构成的。
而人类也有类似的归因倾向。金出武雄在越是高等的动物,解题能力越高,猩猩能够进行某种顿悟,在脑子里就构想出通过堆放墙角的箱子来帮助获取高高吊着的香蕉;而出于进化之树 顶端的人类则具有非比寻常的大脑,在人类整个进化的过程中,解决问题的能力一直在进化,所以说人脑中的神经元最重要的部分是为了解题而存在的也不为过。不同的人只是在解题能力程度上不同,并没有本质上能与不能的差异。
波利亚在《How To Solve It》中另外还举了下面这个例子:
一个原始人站在一条小溪前,他想要越过这条小溪,但溪水经过昨天一夜,已经涨了上来;因此他面临一个问题:如何越过这条小溪。他联想起以前曾经从一棵倒下并横在河上的树木上走过去,于是他的问题变成了如何找到这样一颗倒下并横在溪流上的树木。他环顾四周,发现溪流上没有这样的横着的树木,但他发现周围倒是有不少生长着的树木;于是问题再次变成了:如何使这些树木躺到溪流上。
归约的:首先,原始人通过对一个已知的类似问题的联想认识到一个重要的性质:如果有一棵树横在河上,我就可以借助这棵树过河。这就将一个无法直接解决的问题转化为了一个新的、已知的、并容易解决的问题。值得注意的是这里“联想”是极其重要的一个环节,联想可以将手上的问题与已知的类似问题联系起来,并从后者中吸取能够利用的方法。联想也能够将与问题有关的定理或性质从大脑的知识系统中提取出来。基本上,如果一个联想能够得到某个性质,而这个性质能够或者将问题往上归约一层,或者将条件往下推导一层,这个联想就是有用的。事实上,如果你仔细注意以下解题的过程,你也许会发现,所有的启发式思维方法(heuristics)实质上都是为了联想服务的,而联想则是为了从我们大脑的知识系统中提取出有价值的性质或定理,从而补上从条件到结论、从已知到未知之间缺失的链环。
在这个想像的故事中我们看到了一个问题是如何被一步步一段历史
实际上,人类自从进入理性文明以来,不仅在不断的解题,还在不断的对自身的解题方法进行反省和总结。在这条路上,有一个真正光荣与辉煌的梦想,那就是发现人类解题的所有一般性法则,并借此建造出一台能够解决人类能够解决的所有问题的一般解题机。与物理中的建造永动机不一样,这个梦想并非遥不可及的,自从古希腊哲学家对人类心智的反省思考以来,许多著名的数学和哲学家为此建造了阶梯,Pappus,亚历山大学派最后一位伟大的几何学家,就曾在他恢弘的八卷本《数学汇编》中描述了其中的一种法则,他将它称为“分析与综合”,大意如下:
首先我们把需要求解的问题本身当成条件,从它推导出结论,再从这个结论推导出更多的结论,直到某一个点上我们发现已经出现了真正已知的条件。这个过程称为分析。有了这条路径,我们便可以从已知条件出发,一路推导到问题的解。
波利亚在他的三卷本中把这种做法叫做Working Backwards(倒过来解)。
笛卡尔也曾经试图将人类思维的规则总结为36条(最终完成了21条)。莱布尼兹,现代计算机实质上的发明者,也说到:
在我看来,没有什么能比探索发明的源头还要重要,它远比发明本身更重要。
再后来,捷克数学家波尔查诺也试图总结人类思维的本质规律,他在他的著作《科学的理论》中写道:
我根本不奢望自己能够提供任何超于其他天才所使用过的科学探索方法之外的新方法,从这个意义上,你别指望能在书中看到什么新的东西。但是,我会尽我的全力去总结所有伟大的思想者们共有的、思维的原则和方法,我认为即便是他们自己在思考的时候也未必全都意识到自己在使用什么方法。
再后来,就到了近代,随着科学技术的进步,心理学最活跃的子学科——认知科学——开始辉煌起来,人类开始向思维乃至自我意识的物质基础发起进攻。两位多才多艺的计算机科学家兼认知科学家,Herbert Simon(另外还是经济学家)和Allen Newell写出了世界上第一个一般性解题机的程序(GPS),虽然GPS只能解决很狭窄的一类问题,但这是第一个将“问题解决策略”和“知识”分离开来的程序。显然,在知识之外,人类的思维是有着一些一般性的指导规则的。事实上,波利亚在《数学与猜想》中写道,欧拉是最重数学思维的教学的,欧拉认为如果不能把解决数学问题背后的思维过程教给学生的话,数学教学就是没有意义的。
《How To Solve It》、《数学的发现》、《数学与猜想》)来试图阐明的。波利亚的书是独特的,从小到大,我们看过的数学书几乎无一不是欧几里德式的:从定义到定理,再到推论。是属于“顺流而下”式的。这样的书完全而彻底的扭曲了数学发现的真实过程。举个例子,《证明与反驳:数学发现的逻辑》在附录一中讲了一个非常有趣的例子:柯西当年试图将函数的连续性从单个函数推广到无穷级数上面去,即证明由无穷多个连续函数构成的收敛级数本身也是一个连续的函数,柯西给出了一个巧妙的证明,似乎漂亮地解决了这个问题。然而傅立叶却给出了一个噩梦般的三角函数的收敛级数,它的和却并不是连续的。这令柯西大为头疼,以至于延迟了他的数学分析教程的出版好些年。后来,赛德尔解决了这个问题:原来柯西在他看似无懈可击的证明中非常隐蔽(他自己也不知觉的情况下)引入了一个潜在的假设,这个假设就是后来被称为的“一致收敛”条件。当时我看到这里就去翻我们的数学分析书,发现“一致收敛”这个概念第一次出现的时候是这样写的:定义:一致收敛…
这些一般性的思维方法,就是波利亚用了整整三本书,五卷本(《数学,确定性的丧失》从历史的角度再现了真实的数学发展过程,是一本极其难得的好书。而事实上,从真实的数学 历史发展的角度去讲授数学,也是数学教学法的最佳方法。不过,《数学,确定性的丧失》的弱点是并没有从思维的角度去再现数学发现的思维过程,而这正是波利亚所做的。
所以说,从这个意义上,总结波利亚在书中提到的思维方法,尤其是《How To Solve It》中的启发式思考方法,有这样一些:
- 时刻不忘未知量(即时刻别忘记你到底想要求什么,问题是什么。)莱布尼兹曾经将人的解题思考过程比喻成晃筛子,把脑袋里面的东西都给抖落出来,然后正在搜索的注意力会抓住一切细微的、与问题有关的东西。事实上,要做到能够令注意力抓住这些有关的东西,就必须时刻将问题放在注意力层面,否则即使关键的东西抖落出来了也可能没注意到。
- 用特例启发思考。一个泛化的问题往往给人一种无法把握、无从下手、或无法抓住里面任何东西的感觉,因为条件太泛,所以看起来哪个条件都没法入手。一个泛化的问题往往有一种 “不确定性”(譬如元素的个数不确定,某个变量不确定等等),这种不确定性会成为思维的障碍,通过考虑一个合适的特例,我们不仅使得问题的条件确定下来从而便于通过试错这样的手法去助探问题的内部结构,同时很有可能我们的特例中实质上隐藏了一般性问题的本质结构,于是我们便能够通过对特例的考察寻找一般问题的解。
- 反过来推导。反过来推导是一种极其重要的启发法,正如前面提到的,Pappus在他的宏篇巨著中将这种手法总结为解题的最重要手法。实际上,反向解题隐含了解题中至为深刻的思想:归约。归约是一种极为重要的手法,一个著名的关于归约的笑话这样说:有一位数学家失业了,去当消防员。经过了一些培训之后,正式上任之前,训练的人考他:如果房子失火了怎么办?数学家答出了所有的正确步骤。训练人又问他:如果房子没失火呢?数学家答:那我就把房子点燃,这样我就把它归约为了一个已知问题。人类思维本质上善于“顺着”推导,从一组条件出发,运用必然的逻辑关系,得出推论。然而,如果要求的未知量与已知量看上去相隔甚远,这个时候顺着推实际上就是运用另一个启发式方法——试错——了。虽然试错是最常用,又是也是最有效的启发法,然而试错却并不是最高效的。对于许多题目而言,其要求的结论本身就隐藏了推论,不管这个推论是充分的还是必要的,都很可能对解题有帮助。如果从结论能够推导出一个充要推论,那么实际上我们就将问题进行了一次“双向”归约,如果原问题不容易解决,那么归约后的问题也许就容易解决了,通过一层层的归约,让逻辑的枝蔓从结论上一节节的生长,我们往往会发现,离已知量越来越近。此外,即便是从结论推导出的必要非充分推论(“单向”归约),对问题也是有帮助的——任何不满足这个推论的方案都不是问题的解:譬如通过驻点来求函数的最值,我们通过考察函数的最值(除了函数边界点外),发现它必然有一个性质,即在这个点上函数的一阶导数为0,虽然一阶导数为0的点未必是最值点,但我们可以肯定的是,任何一阶导数不为0的点都可以排除,这就将解空间缩小到了有穷多个点,剩下的只要做做简单的排除法,答案就出现了。再譬如线性规划中经典的单纯形算法(又见《Algorithms》),也是通过对结论的考察揭示出只需遍历有限个顶点便必然可以到达最值的。此外很多我们熟知的经典题目也都是这种思路的典范,譬如《How To Solve It》上面举的例子:通过一个9升水的桶和一个4升水的桶在河里取6升水。这个题目通过正向试错,很快也能发现答案,然而通过反向归约,则能够不偏不倚的命中答案。另一些我们耳熟能详的题目也是如此,譬如:100根火柴,两个人轮流取,每个人每次只能取1~7根,谁拿到最后一根火柴谁赢;问有必胜策略吗,有的话是先手还是后手必胜?这个问题通过试错就不是那么容易发现答案了。同样,这个问题的推广被收录在《编程之美》里面:两堆橘子,各为m和n个,两人轮流拿,拿的时候你只能选择某一堆在里面拿(即不能跨堆拿),你可以拿1~这堆里面所有剩下的个橘子,谁拿到最后一个橘子谁赢;问题同上。算法上面很多聪明的算法也都是通过考察所求结论隐藏的性质来减小复杂度的,譬如刚才提到的单纯形问题,譬如经典面试题“名人问题”、“和最小(大)的连续子序列”等等。倒推法之所以是一种极为深刻的思维方法,本质上是因为它充分利用了题目中一个最不易被觉察到的信息——结论。结论往往蕴含着丰富的条件,譬如对什么样的解才是满足题意的解的约束。一般来说,借助结论中蕴含的知识,我们便可以更为“智能地”搜索解空间。举一个直白的例子,有人要你在地球上寻找一栋满足如下条件的建筑:__层高(填空自己填),__风格,__年代始建,… (省略若干约束条件)。对于这样一个问题,最平凡的解法是穷举地球上每一栋建筑,直到遇到一个满足条件的为止。而更“智能”的(或者说更“启发”的)方法则是充分利用题目里面的约束信息,譬如假若条件里面说要60层楼房,你就不会去非洲找,如果要拜占庭风格的,你估计也不会到中国来找,如果要始建于很早的年代的,你也不会去非常新建的城市里面去找,等等。倒推法是如此的重要,以至于笛卡尔当时认为可以把一切问题归结为求解代数方程组,笛卡尔的万能解题法就是首先将问题转化为代数问题,然后设出未知数,列出方程,最后解这组(个)方程。其中设未知数本质上就是一种倒推:通过设出一个假想的结论x,来将题目对x的需求表达出来,然后顺势而下推导出x。仔细想想设未知数这种手法所蕴含的深刻思想,也就难怪笛卡尔会认为它是那个解决所有问题的一般性钥匙了。
- 试错。试错估计是世界上被运用最广泛的启发法,你拿到一个题目,里面有一些条件,你需要求解一个未知量。于是你对题目这里捅捅那里捣捣,你用上所有的已知量,或使用所有你想到的操作手法,尝试着看看能不能得到有用的结论,能不能离答案近一步。事实上,如果一个问题的状态空间是有限的话,往往可以通过穷举所有可能性来找到那个关键的性质。譬如这样一个问题:有一个囚犯,国王打算处决他,但仁慈的国王给了他一个生还的机会。现在摆在他面前有两个瓶子,一个里面装了50个白球,一个装了50个黑球,这个囚犯有一个机会可以随便怎样重新分配这些球到两个瓶子中(当然,要保证不空),分配完了之后囚犯被蒙上眼睛,国王随机取一个瓶子给他,他在里面摸出一个球(因为蒙着眼睛,所以也是随机抽取),如果白球,则活,否则挂掉。问,这个囚犯如何分配,才能最大化生还几率。结合特例和试错法,这个题目的答案是很容易发现的。这样的题目还有很多。实际上,历史上很多有名的发现也都是无意间发现的(可以看作是试错的一种)。
- 调整题目的条件(如,删除、增加、改变条件)。有时候,通过调整题目的条件,我们往往迅速能够发现条件和结论之间是如何联系的。通过扭曲问题的内部结构,我们能发现原本结构里面重要的东西。譬如这样一个题目(感谢alai同学提供):A国由1000000个岛组成,岛与岛之间只能用船作为交通工具,有些岛之间有船来往,从任意一个岛都可以去到另外任一个岛,当然其中可能要换船。现在有一个警察要追捕一个逃犯,开始时他们在不同的岛上,警察和逃犯都是每天最多乘一次船,但这个逃犯还有点迷信,每个月的13日不乘船,警察则不迷信。警察每天乘船前都知道逃犯昨天在哪个岛上,但不知道他今天会去哪个岛。请证明,警察一定可以抓到逃犯(即到达同一个岛)。通过拿掉题目中一个关键的条件,观察区别,然后再放上那个条件,我们就能“感觉”到题目的内在结构上的某种约束,进而得到答案。
- 求解一个类似的题目。类似的题目也许有类似的结构,类似的性质,类似的解方案。通过考察或回忆一个类似的题目是如何解决的,也许就能够借用一些重要的点子。然而如何在大脑中提取出真正类似的题目是一个问题。所谓真正类似的题目,是指那些抽象结构一样的题目。很多问题表面看是类似的,然而抽象结构却不是类似的;另一些题目表面看根本不像,然而抽象层面却是一致的。表面一致抽象不一致会导致错误的、无效的类比;而表面不一致(抽象一致)则会阻碍真正有用的类比。《Psychology of Problem Solving》里面对此有详细 的介绍。后面也会提到,为了便于脑中的知识结构真正能够“迁移”,在记忆掌握和分析问题的时候都应该尽量抽象的去看待,这样才能够建立知识的本质联系,才能够最大化联想空间。
- 列出所有可能跟问题有关的定理或性质。这个不用说,我们在最初学习解题的时候就是这么做的了。
- 考察反面,考察其他所有情况。很多时候,我们在解题时容易陷入一种特定的手法,比如为什么一定要是构造式的来解这个题目呢?为什么不能是逼近式的?为什么一定要一步到位算出答案?为什么不能从一个错误的答案调整到正确答案?为什么这个东西一定成立?不成立又如何?等等。经典例子:100个人比赛,要决出冠军至少需要赛多少场。
- 将问题泛化,并求解这个泛化后的问题。刚才不是说过,应该通过特例启发思考吗?为什么现在又反倒要泛化呢?实际上,有少数题目,泛化之后更容易解决。即,解决一类问题,比解决这类问题里面某个特定的问题还要容易。波利亚称之为“发明者悖论”,关于“发明者悖论”,《数学与猜想》第一卷的开头有一个绝妙的例子,可惜这里空间太小,我就不摘抄了- _-|||
以上是我认为最重要的,也是最具一般性的、放之四海都可用的思维法则。一些更为“问题特定”的,或更为现代的启发法,可以参见《如何解题:现代启发式方法》以及所有的算法书。不过,在结束这一节之前,还有两个有趣的启发法值得一提:
- 下意识孵化法。这个方法有点像老母鸡孵小鸡的过程:我们先把问题的吃透,放在脑子里,然后等着我们的下意识把它解出来。不过,不宜将这个方法的条件拉伸过远,实际上,除非能够一直保持一种思索的状态(金出武雄所谓“思维体力”),或者问题很简单,否则一转头去做别的事情之后,你的下意识很容易就把问题丢开了。据说庞加莱有一次在街上,踏上一辆马车的那一瞬间,想出了一个重要问题的解。其他人也像仿效,结果没一个人成功。实际上,非但马车与问题无关,更重要的是,庞加莱实际上在做任何事的时候除了投入有限的注意力之外,其他思维空间都让给了那个问题了。同样,阿基米德从浴缸里面跳出来也是如此;如若不是经过了极其痛苦和长时间的思索,也不会如此兴奋。如果你也曾经花过几天的时间思考一个问题,肯定也是会有类似的经历的。
- 烫手山芋法。说白了,就是把问题扔给别人解决。事实上,在这个网络时代,这个方法有着无可比拟的优越性。几乎任何知识性的问题,都可以迅速搜索或请教到答案。不过,如何在已知知识之外发掘出未知知识,如何解决未知问题,那就还是要看个人的能力了。数学界流传一个与此有关的笑话:如果你有一个未解决问题,你有两个办法,一,自己解决它。二,让陶哲轩对它感兴趣。