Updated(2008-7-24):更新见正文部分,有标注。
其实下文的绝大部分内容对所有学习都是同理的。只不过最近在正儿巴经地学算法,而后者又不是好啃的骨头,所以平时思考总结得就自然要比学其它东西要多一些。
问题:目前几乎所有的算法书的讲解方式都是欧几里德式的、瀑布式的、自上而下的、每一个推导步骤都是精准制导直接面向目标的。由因到果,定义、引理、定理、证明一样不少,井井有条一丝不乱毫无赘肉。而实际上,这完全把人类大脑创造发明的步骤给反过来了。看起来是阳关大道,实际上车马不通。
而对读者来说,这就等于直接告诉你答案&做法了,然后让你去验证这个答案&做法是可行&成立的。而关于答案&做法到底是怎么来的,从问题到答案之间经历了怎样的思维过程。却鲜有书能够很好的阐释。就我有限的阅(算法)书经验,除了波利亚的《怎样解题》还算合格之外(也并非最理想),其它的(包括有名的《算法导论》、《如何解题:现代启发式方法》、《Algorithms》、《编程珠玑》,甚至TAOCP——公平地说由于高老大对算法领域历史了解得非常通透,所以许多地方能够从原始脉络来讲述一个问题,譬如令人印象深刻的从竞赛树到堆的讲解就寥寥一页纸道出了堆这个数据结构的本质来,而像刚才列的几本有名的书却都没有做到),在思维的讲述上都算不上合格(当然不是说这些书没有价值,作为知识性的参考书籍,它们将知识整理出系统结构,极大的便利了知识的掌握,就像《什么是数学》所做的工作一样),为什么我这么说呢,因为我发现每每需要寻找对一个算法的解释的时候,翻开这些书,总是直接就看到关于算法逻辑的描述,却看不到整个算法的诞生过程背后的思想。
我们要的不是相对论,而是诞生相对论的那个大脑。我们要的不是金蛋,而是下金蛋的那只鸡。
Update(2008-7-24): 收到不少同学的批评,想来这个开头对一些著作的语气过重了,实际上,注意,我完全不否认这些著作的价值,我自己也在通过阅读它们来学习算法,并且有很多收获。这篇文章更多的只是建议除了阅读这些著作之外还需要做的功课。此外,对于这类知识讲述(欧几里德)方式的批判西方(尤其是在数学领域)早就有了,早在欧拉和庞加莱的时候,他们俩就极其强调思维的传授,欧拉认为如果不能传授思维,那数学教学是没意义的。而庞加莱本人则更是对数学思维有极大的兴趣和研究(我前阵子在讨论组上还转载了一篇庞加莱的著名演讲,就是说这个的,参见这里)。我只是在说目前的算法书没有做到思维讲述的层面,因此建议阅读这些书之余应该寻找算法的原始出处,应该寻根究底,多做一些功课,知道算法到底是怎么诞生的,并且我说明了为什么应该知其所以然,有哪些好处(见下文),我还给了几个例子譬如红黑树作者讲红黑树的,g9讲后缀树的,以及Knuth讲heap的。唉,其实挺正统的观点,授人以渔,不管是东方西方都有类似的古老谚语。而我只是从认知科学的角度加了点解释,windstorm称之为“解释文”。而已。可惜被开头的语气搞砸了,算了,既发了也就不改了。
为什么会这样,其实是有原因的。
我们在思考一个问题的过程中有两种思维形式:
- 联想:这种思维某种程度上可以说是“混乱”的(虽然从一个更根本的层面上说是有规则的),所谓混乱是指很多时候并不确定联想到的做法最终是否可行,这些联想也许只是基于题目中的某个词语、语法结构、问题的某个切片、一些零星局部的信息。这个过程是试探性的。最后也许有很大一部分被证明是不可行的。很多时候我们解决问题用的都是这种思维,简言之就是首先枚举你关于这个问题能够想到的所有你学过的知识,然后一一往上套看看能否解决手头的问题。这种思维方式受限于人脑联想能力本身的局限性。我在《跟波利亚学解题》中就提到了几个例子。联想本身需要记忆提取的线索,所以受到记忆提取线索的制约,如果线索不足,那怎么也联想不起来。而提取线索的建立又取决于当初保存记忆的时候的加工方法(《找寻逝去的自我》里面有阐述),同时,面对一个问题,你能够从中抽取出来的联想线索又取决于你对问题的认识层度/抽象深度,表浅的线索很可能是无关的,导致无效的联想&试错(《Psychology of Problem Solving》里面有阐述)。总之,联想这个过程充满了错误的可能。
- 演绎&归纳:演绎&归纳是另一种思维形式。它们远比联想有根据。其中演绎是严格的,必然的。归纳也是有一定根据的。在面对一个问题的时候,我们有意无意的对问题中的各个条件进行着演绎;譬如福尔摩斯著名的“狗叫”推理——狗+生人=>吠叫 & 昨晚狗没有叫 => 那个人是熟人。就是一个典型的对问题的各个条件进行演绎的推理过程。还有就是通过对一些特殊形式的观察来进行归纳,试图总结问题中的规律。然而,不幸的是,面对复杂的问题,演绎&归纳也并不总是“直奔”问题的解决方案的。人的思维毕竟只能一下子看到有限的几步逻辑结论,一条逻辑演绎路径是否直奔答案,不走到最后往往是不知道的,只要答案还未出现,我们大脑中的逻辑演绎之树的末端就始终隐藏在黑暗之中。而当最终答案出现了之后,我们会发现,这棵演绎之树的很多分支实际上都并不通往答案。所以,虽然演绎&归纳是一种“必然”的推理,然而却并不“必然”引向问题的结论,它也是试错的,只不过比联想要更为靠谱一些。
既然认识到,人类解决问题的两大思维方式实际上都是有很大的试错成分的(好听一点叫“探索”),那么就不难意识到,对一个问题的思考过程实际上是相当错综复杂的,而且充满了无效分支——在思考的过程中我们也会不断的对分支进行评估,做适当的剪枝——因此当我们找到问题的解之后,一来思维的漫长繁杂的过程已经在大脑里面淡化得差不多了,只有那些引向最终结论的过程会被加“高亮”——我们在思考的过程中本就会不断的抛弃无效的思路,只留下最有希望的思路。简而言之就是最后证明没用或者早先我们就不抱希望的一些想法就被从工作记忆中扔掉了。二来,思考过程是我们的空气和水,而“鱼是最后一个感觉到水的”,我们感觉不到思维法则本身的存在,我们只是不知不觉运用它。三来,由于我们的目标是问题的解,解才是我们为之兴奋和狂喜的东西,而不是求解的过程,过程只是过程,目的才是目的。这就像一个寻宝者,在漫长曲折的寻宝历程之后,在找到宝藏的时候,他会对宝藏感到狂喜(记得阿基米德的“找到了!”吗?)而迫不及待地要展示出来,而漫长的思考本身却成了注脚。我们是有目的的动物,目的达到了,其它的就相对不那么重要了。最后,对于传授知识的人,也许还有其四:感到介绍思维过程是不相干的,毕竟思维过程并不是算法问题的解,算法问题的解才是算法问题的解。然而不幸的是,忽视到达解的那个过程实际上却变成了舍本逐末。我们看到的是寥寥数行精妙绝伦的算法,然后仰天长叹自己想不出来啊想不出来。为什么想不出来,因为你不知道那短短数行算法背后经历的事怎样漫长的思考过程,如果问题求解是一部侦探小说,那么算法只是结局而已,而思考过程才是情节。
既然如此,也就难怪古往今来算法牛人们算法牛,但却没有几个能真正在讲述的时候还原自己的思维过程的(那个“ 渔”字),手把手的教学生走一遍推理的思路,就可以让学生获得思维过程的训练。金出武雄在《像外行一样思考,像专家一样实践》中说写论文应该写得像侦探小说一样,我很赞同。欧几里德式的介绍,除了提供枯燥的知识之外,并没有提供帮助人获得知识的东西——思维(关于对数学书籍的欧几里德式写法的批评其实也是由来已久了,并且有人呼吁了好几种其它的教学方法)。从这方面,我们所尊敬的一些“圣经”级书籍在传道授业上还不如侦探小说,前者是罗列一大堆知识,后者则是阐述获得知识的过程——推理&联想。
然而,我们都是人,人类该有的思维形式,我们难道不是都有吗。既然如此,思维本身又有什么需要一遍遍教的呢?
并非如此。
讲述思维过程而非结果有几个极其重要的价值:
- 内隐化:思维法则其实也是知识(只不过它是元知识——是帮助我们获得新知识的知识);是内隐的记忆。我们在思考的过程中觉察不到思维法则的作用,它们却在幕后实实在在的左右着我们的思维轨迹。要将思维方法内隐化,需要不断练习,就像需要不断练习才能无意识状态下就能骑自行车一样。
- 跨情境运用:思维法则也是知识记忆,是问题解决策略。既然是记忆,就受到提取线索的制约,这就是为什么当波利亚告诉你要“注意未知数”之后你还是不能真正在所有需要你“注意未知数”的地方都能提醒自己“注意未知数”。很多时候未知数是很隐蔽的,未知数并不会总是头顶一个大帽子上面写着“我是未知数”。所以很多时候缺乏对这个策略的“提醒”线索,这也是为什么你学会了在解决数学问题的时候“注意未知数”却不一定能在解决现实生活中的问题中时刻都能“注意你的未知数”(《你的灯亮着吗?》整本书的价值便在于此),因为解数学题和解决生活中问题的场景不一样,不同的环境线索,在你大脑中激发的记忆也不一样。就连问题求解中,不同的问题之间的细小差别也可能导致思维轨迹很大的不同,有时你的注意力会被一个无关线索激发的联想吸引开去,忘记如“注意你的未知数”这样的重要法则。而一本从思维角度来讲问题求解的书则可以一遍遍将你置于不同的问题场景下然后在该提醒你的时候提醒你,让你醒悟到“哦,原来这个时候也应该想到这个啊。”,做多了这样的思维演习你就会逐渐从中领悟到某种共性,并将一些思维习惯得到强化,于是终于能够在需要运用某策略的时候能适时的想起来了。
- 对问题解的更多记忆提取线索:我们平时学习算法时几乎仅止于“理解”,别人把一个方案放在你面前,你去验证一下,心说“哦,不错,这个的确可以工作”。然后就没了。稍微简单一点的算法还好,复杂一点的对于记忆的负担是很大的,这就是为什么有时候我们看到一个绝妙的解法,这个解法看上去不知道从哪里来的,但经过我们的理解,却发现是对的,我们感叹,真巧妙,结果一些天之后,别人问起这个问题,我们说:“唉,那是个多么巧妙的算法啊,但是我只记得它巧妙,却不记得它到底是怎样的了。” 为什么?因为在不知其所以然的情况下,算法只是一堆离散的机械步骤,缺少背后的思想的支撑,这些步骤之间就没有一个本质层面上的关联(先知亚里士多德早就指出:学习即联接)。所以就跟背历史书也没多大区别。然而,知道了算法是怎样一步步被推导出来的,我们就一下拥有了大量的记忆提取线索:对算法发现过程中的任何一个关键步骤(尤其是本质)的回忆都可能使我们能够自己动手推导出剩余的内容。譬如你知道堆(heap)是怎样由朴素的决策树演化而来的,它又是为了解决什么问题的,你即便忘记了具体的细节,也可以自己推导出来。譬如你知道KMP算法的本质在于消除回溯,至于如何消除回溯却并不是那么难以推导的,所以即便忘了也可以借助于大脑的逻辑演绎能力再现出来。譬如你知道Tarjan算法其实只是从后序遍历经过两个优化调整而来的(其中并査集的使用其实只是优化手段——为了能够迅速判断祖先节点是谁——而非算法本质——当然,算法设计的主要任务本来就是通过问题条件中蕴含的知识来“消除冗余计算”和“避免不必要计算”,所以你也可以说并査集的使用是关乎本质的,只不过,知道了为什么需要引入并査集,就会强烈地感觉到一切是顺理成章的了),那这个出了名的绕人的算法也就不那么难以理解和记忆了。譬如你知道排序的本质,就能够对什么是最优排序,为什么它是最优排序有深刻的认识。四两拨千斤。
- 包含了多得多的知识:记一个算法,就只有一个算法。一个萝卜一个坑。就好比背99乘法表只能解决乘法问题一样。而记背后的思想,却有助于解决一类问题。思想所处的抽象层面往往比到处都是实现细节的算法本身要低,越是低的抽象层次,越是本质,涵盖范围越是广泛。数学的发展本身就体现了这个过程,抽象代数就是非常好的例子。算法诞生过程中的思路往往包含了比实际算法更本质得多的知识,实际算法乃至算法的某个特定语言的实现包含了太多表面的不相干知识,它们会阻碍对本质的理解。
- 重在分析推理,而不是联想:学了一大通算法和数据结构之后的一个副作用就是,看到一个问题之后,脑袋里立即不管三七二十一冒出一堆可能相干的数据结构和算法来。联想是强大的思维捷径,在任何时候都会抢占大脑的工作记忆,由不得你控制——比如我问你“如何寻找区间的最大值”,首先进入你的意识的肯定就是学过的那个算法,甚至算法的实现细节都一一跳了出来,也许最先跳出来的还是算法实现中某个最容易弄错的边界细节,或是某个比较tricky的实现技巧!然而这些其实根本不反映一个算法的本质,结果想来想去总是停留在问题的表层。而另一方面,重在思维的传授则可以让人养成从问题本质入手,逐步分析推理的习惯,而不是直接生搬硬套。当然,完全不可否认,联想本身也是极其重要的思维方法,甚至可以说是人类思维最重要的特征。很多时候我们并不知道问题的本质是什么,就需要靠联想、类比来领路探索。只不过,养成优先从问题的本质入手进行考察的好习惯绝对是有更大的好处的。
那到底什么样的才算是授人以渔的呢?波利亚的《如何解题》绝对算是一本,他的《数学的发现》也值得一看。具体到算法书,那就不是光看text book就足够的了,为了深入理解一个算法的来龙去脉前因后果,从一个算法中领悟尽量深刻的东西,则需要做到三件事情:
- 寻找该算法的原始出处:TAOCP作为一个资料库是绝对优秀的,基础的算法只要你能想到的,几乎都可以在上面找到原始出处。查到原始出处之后(譬如一篇paper),就可以去网上搜来看了。因为最初的作者往往对一个方案的诞生过程最为了解。比如经典数据结构中的红黑树是出了名的令人费解的结构之一,但它的作者Sedgewick一张PPT,给你讲得通通透透,比算法导论上的讲法强上数倍。
- 原始的出处其实也未必就都推心置腹地和你讲得那么到位:前面说过,算法设计出来了之后人们几乎是不会去回顾整个的思维过程细节的,只把直指目标的那些东西写出来。结果就又是一篇欧几里德式的文章了。于是你就迷失在一大堆“定义”、“引理”、“定理”之中了。这种文章看上去整个写得井井有条,其实是把发明的过程整个给颠倒过来了,我一直就想,如果作者们能够将整个的思路过程写出来,哪怕文字多上十倍,我也绝对会比看那一堆定义定理要容易理解得多。话说回来,怎么办?可以再去网上找找,牛人讲得未必比经典教材上的差。那倘若实在找不出好的介绍呢,就只能自己揣摩了。揣摩的重要性,是怎么说都不为过的。揣摩的一些指导性的问题有:为什么要这样(为什么这是好的)?为什么不是那样(有其它做法吗?有更好的做法吗?)?这样做是最好的吗?(为什么?能证明吗?)这个做法跟其它的什么做法有本质联系吗?这个跟这个的区别是什么?问题的本质是什么?这个做法的本质又是什么?到底本质上是什么东西导致了这个做法如此..?与这个问题类似的还有其它问题吗?(同样或类似的做法也适用吗?)等等。
- 不仅学习别人的思路,整理自己的思路也是极其重要的:详见《跟波利亚学解题》的“4. 一个好习惯”和“7. 总结的意义”。



获益匪浅!
我也总是在思考此类问题,您的观点让我的理解又深入一层,学习中
大学时候,借了部分算法书。没有看下去。博主的话让我有了新的学习打算。
针对任何问题的解决之道,都可以以此引申开去,在获得答案的时候,有必要对于获得答案的过程进行细致地剖析。以往,自己在解决问题的过程中,效率第一,直接进入知识库进行查找,然后联想相关的资料,最终把问题的关键点找到,然后就把问题搞定了,最多是回头再回想一下整个过程而已。看了上面的论述,我觉得,若要能够深入进入、成为更专业的人才,对于解决问题的过程本身的深入思考和总结是非常有必要的,要多看、多想、多总结了。受教!
对问题思考推理的过程,其价值远高于得到问题的结果。而且注重解决问题的思考过程,能更好的上升我们对实际问题解决的能力。
Pingback: chuan最近小结 - qinchuan的Jimdo网站!
你说的有些道理,尤其是其中的“试错法”,在实际中用的很多。但是,类似《算法导论》中的经典书籍中并没有说明算法作者为什么想到这么解决问题,其思维过程是什么(其实,不知你发现没有,数学书籍中这类的事情也很多,作者只关心是否将解决方法说明白和他的论证方法是否出错。)我想其中的原因也有:当我们看到很多例子后,我们会去总结解题的思路,所以“见多识广”也应该是解决方法的一条途径。
最近在看《算法导论》中的动态规划和贪心算法两章的内容。在动态规划中,最重要的步骤应该算是如何将问题分解为子问题,并论证分解的正确性。倘若过了这关,后面的内容其实都好说。而作者其实并没有在这个“最重要的问题”上着重讲述。
Pingback: [转载]为什么你应该(从现在开始就)写博客 » 心智的力量 - 天下武功唯快不破,做一个实实在在的实用主义者
文中的核心问题其实也是常常挂在人们嘴边的问题,如果获得创新能力。创新本质具体艺术性,没法教程化,技术化。不过创新的基础倒是有技术化的空间。
Pingback: 知其所以然~~~ | 【仅供预览】Leafiy™
Pingback: 心博 » 为什么你应该(从现在开始就)写博客
Pingback: Head First系列导言(#rev 0) | Project Maple
Pingback: [BetterExplained]为什么你应该(从现在开始就)写博客 | 麦克 Magic Coder
Pingback: 知其所以然(续) | w3er
Pingback: [转]为什么你应该(从现在开始就)写博客 « mengxin's blog
Pingback: 知其所以然(三)——为什么算法这么难?
博主可能会觉得读此书A Discipline of Programming会非常满足,因为Dijkstra老爷爷和你一样对只写结果的算法书很是不满:)
看了博主的文章,很有感触。我大学两年来,也一直在思考类似的问题,到底是什么夺走了大学生的学习兴趣,最后,我追踪到课本和教育方式上。
我的感觉是,很多课本、很多课堂都太“功利”,正如你所说,直接给个结果,而不讲问题到底是什么?问题从何而来。对于问题本身理解的丧失,也是导致对解决问题兴趣丧失的原因。
我也是学计算机的,在做ACM类似的题时,虽然脑子不够聪明,但我很注重解题的原创性,我觉得原创很重要,要不然,别人的算法是怎么诞生的呢?呵呵。
我没看过像《如何解题》此类的书,看博主多次提到,我很感兴趣,可否推荐推荐这一系列的书呢,多谢了。
Pingback: [zz]知其所以然(三):为什么算法这么难?-刘未鹏 « Apollo Connecting the World
Pingback: [转载] 为什么你应该(从现在开始就)写博客
完全赞同,我觉得作者是心理学专业的啊??
Pingback: 推荐读书《暗时间》
Pingback: 转:为什么算法这么难? | South♂楠个人博客
Pingback: 转载:知其所以然(三):为什么算法这么难? | 问雅轩
Pingback: 为什么要写博客? | IT 思维(SIWEI)
Pingback: 为什么你应该(从现在开始就)写博客(轉載) | MemoryTrash
Pingback: 为什么你应该(从现在开始就)写博客[转] | mengxin's blog
Pingback: 为什么你应该(从现在开始就)写博客[转] « mengxin's blog
Pingback: 草草de小站 -
Pingback: 转:为什么你应该(从现在开始就)写博客 « Mr Onetwo
Pingback: 知其所以然(三):为什么算法这么难? | 风的天地
Pingback: 知其所以然(续) | 风的天地
Pingback: 【转载】为什么你应该(从现在开始就)写博客
Pingback: 为什么你应该(从现在开始就)写博客 | 纯真年代
Pingback: 为什么你应该(从现在开始就)写博客(刘未鹏) | 纯真年代
思想所处的抽象层面往往比到处都是实现细节的算法本身要低,越是低的抽象层次,越是本质,涵盖范围越是广泛。
“越是低的抽象层次,越是本质,涵盖范围越是广泛”
不是抽象层次越高,涵盖范围越是广泛,越本质吗? 求解
Pingback: 知其所以然(以算法学习为例)续 | 冷风留痕
Pingback: TopDigger » 推荐一些常逛的牛人博客
Pingback: 知其所以然(续) | 吃杂烩
Pingback: 知其所以然(三):为什么算法这么难? | 吃杂烩
Pingback: 孙吾饭的游乐场 | 暗时间
不错!拜读了!
《算法导论》买了三年了,还在书架上躺着,看不下去。。。惭愧啊
looking is the one thing all of us love to complete (specially http:///www.sportrakuten.com/categories/1369471516-183.html レイバン(RAY BAN) me), as i don’t learn how but looking is just one activity gives us eminence contentment and relaxation back-links we usually are tired or maybe frustrated or maybe irritated, but while using the ever escalating targets in addition to office update it offers became difficult for us to uncover some the perfect time to hang out with the family and enjoy this time while rooming around within the streets connected with market.
But as we always say there is a alternative for every problem in addition to situation on this planet, all you should do is hunt for that alternative with ‘something different’ mind-set. And be the very reason that any of us put together a innovative method connected with shopping http://www.abcsnk.com/adidas-スパイクサッカー-アディピュア-11pro-c-22_23_29.html アディピュア11pro which often know seeing that online looking method. But currently being this principle http:///www.sportrakuten.com サングラス通販 new electrical power quarries which might be there from http://www.sportrakuten.com/categories/1369471366-179.html レイバン サングラス the mind of people related towards same and i am here in order to resolve those per se.
But today you will discover thousands connected with products and this can be purchased by an website starting at a bugger into a flat and it’s impossible for people like us to cover the many in just one discussion per se therefore today we will be only dealing with facts relates to online looking of shoes and boots for adult males.
Buying a couple your beloved Adidas shoes and boots from these internet retailers is amongst the easiest thing on this planet, but for making it basically easy you could http://www.abcsnk.com ナイキ 通販 have to address few on the things or maybe points which might http://www.abcsnk.com/adidas-スパイクサッカー-プレデター-アディダス-11-c-22_23_25.html adidas プレデター be listed underneath.
http://www.jordanjpsneaker.com/nddbc.html
http://www.hotsneak.com/categories/nddbc.html
http://www.sportsbrand-nike.com/nddbc.html
粗读过一遍,以此为记,关于侦探小说的看法,不错,这样说来侦探小说确是个好东西,其他看法,我现在只能说更妙
这样说吧,最近我在想一个问题,到底别人应该给我们什么?反过来讲,书的作者是否有义务写出些过程来?或者掌握资源的人应该为我们这些不能分配资源不拥有资源的人做点什么?伦理政……考虑到东方人心的本性,实现这个有几难?对于西方社会来说,有些做法,有些认识打小就已有经历和体会,深入骨髓,可我们却没有丝毫,我们的环境不是为了给予而构造的……大家,应该都懂的,所以,我们好像比较愤……现在我对自己说,东西就是个东西,是属于东西自己的东西,没有得到这个概念,除了围起来,盖起来遮住的那些“绣花枕头”,还有干的男性上一辈……”给的“那些纯爱,但,那其实是以物易物纯物现象,所以,学到知识,付出是肯定的,如果不打算以物易物那肯定要付出更多,要打破人为的禁锢和封锁,要藐视那些绣花皮和其内含物,这就是我们获取知识时要走的路……历史终究会被湮灭,因为经历者写者读者观点平台不一样,留下来的,也不过是一部部小说,所以,自己去发现去……吧
个人觉得像是数学,算法之类的教材完全可以写成历史小说之类的题材,让人了解事物发展规律,创新的过程,同时学到知识。现在的大学教材看起来一点兴趣都没有,都是很枯燥的灌输,完全不知道个所以然来,如果没有兴趣的支撑很难坚持读下去。
其实我也一直在想应该怎么学习,怎么了解到发现这些成果的人到底是怎么想的,怎么才能获得所谓的元知识。国内工具书一般的教材很多时候实在是倒人胃口,国外的一些教材对自学者确实很友好,但也如同作者所说还是差了些什么。也许,这就是大学存在的意义?