invalid s
开宗明义:算法不是什么高级知识,它是初中甚至小学就可以掌握的东西。只不过,应试教育通过持续十年的努力,把你理解算法的能力剥夺了而已。
说白了,算法就是“利用自然/数学规律达到我们预定目的”的思路。
要学会这个思路,其实不难。
比如,我们知道,电流通过电阻会发热;那么,当我们需要煮饭时,是不是可以通过选取一个合适的电阻,利用它的热量呢?
然后,细化问题:当我们要利用220v电压,得到2000瓦的煮饭功率时,该如何选择电阻呢?电阻本身会不会被烧坏?我们怎么避免它被烧坏?
继续细化:2000瓦的发热功率,要避免温度无限堆积,我们需要选择一个合适的散热效率;牛顿散热公式很好找,然后我们知道温度差越大散热越快,因此温度不可能无限提升。
继续:假设烧饭用的电热丝最佳温度是500~800度,我们怎么凑得这个值呢?
还能再进一步:我们是不是可以放个温度计在锅的支撑点/接触面上,当锅被烧干时自动断电呢?
继续拆分这个目标:双金属片、热电偶、磁体的居里点等等,都可以代替温度计,从而使得温度探测装置结构更简单、实现更便宜同时又更耐用。
你看,电炉、电饭煲等等“算法”,已经呼之欲出了。
再如,我们知道气体受热膨胀;燃料燃烧产生大量热;我们知道杠杆、轮轴原理……
那么,能不能组合这些东西,得到……内燃机呢?
细化:我们需要一个气缸,让燃料在里面燃烧;然后需要一个大小合适的活塞,利用燃烧后的高温高压气体推它;我们需要曲柄、连杆,把活塞的往复运动变成旋转……
困难:等等,这样只能推一下!
解决:加一个飞轮,利用它的惯性储能;然后借助飞轮储存的动能,控制气缸上面气阀的开闭;再借助齿数比以及凸轮,使得气缸上面的气阀在合适的地方动作——从而形成“进气、压缩、做功、排气”四个冲程。
困难:怎么在合适的时机添加合适的燃料?怎么使其燃烧?
解决:喷油嘴、雾化器、火花塞(柴油机还可压燃)……同样使用凸轮控制,使其恰到好处的动作……
你看,四冲程内燃机“算法”就设计出来了。
继续,收音机,电视机……继电器,逻辑门,加法器……只要你稍有了解便会发现,它们统统是这个思路。
什么思路呢?
1、提出一个大而笼统的问题
2、把大而笼统的问题清晰化,然后拆分成一堆较小、较清晰、较容易解决的问题
3、解决每一个小问题
4、组合一大堆小问题的解决方案,组合得到大问题的解决方案
换句话说,解决实际问题并不是一问一答,套个合适公式就能完事的——凡这样想的,才是不折不扣的反智。
恰恰相反,实际问题总是含糊的,有时候连个大方向都不会有。
领导/老板绝不会对你说,为了解决人民群众的做饭需要,请你算一算220v电作用于100欧的电阻,产生的热功率是多少。
对不起,他们往往是外行,压根不可能把问题问到这个程度;而且问到这个程度哪够!你找个收音机用的糯米粒一样的100欧电阻试试,看看它能不能扛一秒。那么,适合做饭需要的电阻应该长什么样子,你能把这个需求清晰的提出来吗?
哪怕他们是内行,让你发明扫地机,也绝不会让你算电阻发热量——有提这种问题的功夫,他们自己就算出来了。
他们需要的,是你综合利用自己掌握的知识,替他们考虑好需要注意需要解决的一切一切,并且解决它。
因此,你得综合自己的知识,自己学着提出问题。
任务:做个利用电做饭的锅,尽可能自动、智能
你晕不晕?但这才是实践问题。这才是实际生活中、工厂里,老板/领导真正会提的问题。
要解决这类问题,你得反过来,自己给自己提问题。
第一个问题,用电做饭是什么原理;第二个问题,我得考虑哪些方面,才能让用户可以安全使用;第三个问题,我得如何设计操作界面,才能让用户觉得它易用甚至智能;第四个问题,我怎么实现它们;第五个问题,如何证明我的方案可行、还有没有更好的方案;第六个问题,如何压缩成本……
通过问自己问题,帮自己把目标清晰化、帮自己寻找解决问题的步骤、帮自己设计解决问题的方案、帮自己证明解决方案的可行性/经济性、帮自己寻找简化方案/更优方案……你看,有无穷无尽的事情要做。
计算机算法也是类似的东西。它要求我们灵活运用我们掌握的知识,凑出我们需要的结果来。
比如说,识别图像边缘,这得怎么做?
首先,问自己一个问题:什么是图像边缘(请尽量用数学语言回答,做不到就得多锻炼)
然后,继续问:我这个回答可靠吗?会不会像“柏拉图的人”一样,被人用“拔毛鸡”蒙混过关?如果遇到这种情况,怎么办?还是只能忍受?
最后,如何用计算机语言实现我的想法?
你看,学会问问题,学会把模糊的目标清晰化、数学化,算法的问题就解决了一半。
另一半是,寻找一条路,解决这种在未经训练者看来压根就无法回答的问题——这一半的难度,往往比“提出问题”又大了无数倍。
为了解决这类问题,你必须创造性的使用你掌握的知识。
热电偶受热产生电压?那么搭配上电压表它就是温度计。
石英受压产生电压?那么把它做成薄膜、当它随着声波颤动时,其上的电压必然反映了声波波形——不够完美?那是因为共振、分割震动等等问题造成的,我可以如此如此的建模从而使其可计算;然后如此如此的修改方案,以便影响其中的某个参数,从而得到完美的波形。
信号电压太过微弱?有很多很多种物理过程,可以把微弱的输入按比例放大。比如油门线上施加的微小的力和发动机输出的强劲功率之间的关系。
我需要寻找数学/物理原理类似的过程。这玩意儿往往并不是天然存在的,但我可以利用现象A和现象B,然后如此组合它——看,三极管出现了!
类似的,我们需要让杂乱无章的一堆数字有序,怎么办?
很简单,我们都见过水和油的分层现象。它们为何会分层?遵循怎样的物理规律?我如何提取其中的核心部分、尽量简化我的实现?
冒泡算法呼之欲出。
先学会提问题,再学会创造性的解决问题;最后,把创造性的解决方案拆分、实现——这就是算法。
很明显,提问题和解决问题并没有明显的界限。你必须融会贯通它。这需要持久、刻苦的训练——哪怕是香农,他也没可能一步到位的搞出哈夫曼编码算法。
必须在这两个方面足够训练有素,你才可能理解香农的伟大。
绝大部分比较难的算法已经被人解决了。我们可以学习他们的解决思路,然后解决实践中遇到的那些更为简单但并不能直接套公式的问题。
如果你曾经尝试过去想“为什么欧几里得会弄出几何学”“为什么某某定理可以这样证”“为什么他们就能想到这样去证”,那么提问题和解决问题的一般思路就学到手了——如果你这样学,那么初高中学到的每一个知识点,都在教你如何解决问题、如何设计算法(所有“按步骤处理即可解决问题”的步骤的设计,都是广义的算法)。
换句话说,你需要锻炼自己主动的提出问题、寻找解决问题的途径能力,而不是被动的记忆“套公式解决能套公式解决的问题的方法”。
但是,国内的应试教育以做题为目的。
学了轮轴?看,这道题要用到轮轴,我们要这样套公式;那道题是另一种题型,套公式得那样套——总结:关于轮轴的题型一共X种,它们的解法分别是#*&¥%#*……
久而久之,你们就只会背公式套公式了——你说手电筒?那玩意儿那么复杂书上没说我怎么可能知道!
绝大多数人,最终都学的不仅不会问问题,更不会解决问题。他们只是会套公式而已。
当手电筒都能难住你时,哈夫曼?差着十万八千里呢。这不是拿世界级难题难小学生吗。
手电筒真的不是个比喻。
很多人的确没有能力理解这种最浅最直接的知识:代码是如何控制硬件的?
你看,“老鼠夹子抓老鼠不是老鼠夹子有智能,而是我们自己想办法组合了杠杆、弹簧等东西,使得它可以在小动物碰触时动作”这个幼儿园小朋友都能懂的原理他们懂吗?懂了还会契而不舍的不断追问“计算机究竟是怎么认识0和1”吗?
这种程度的换位思考/反向思考都办不到,还能指望他们“自发寻找日常问题的解决方案”吗?还可能指望他们解决别的“日常动脑”的人也需要思考片刻的“难”题吗?
但是,哪怕只是当一个稍微不那么尸位素餐的、中小企业的底层领工者/技术员,完全不会动脑子,可能吗?
总结起来就一句话:算法很简单,中小学甚至大字不识的人都能学会;它只是要求你自己动脑子、创造性的使用你学到的知识而已。
创造性几乎是人类这个物种与生俱来的,没人知道该如何教会别人;但压抑它、剥夺它,却并不难。