《编程原来是这么回事》算法篇(中)
4. 怎么选择合适的算法?
在大多数情况下,我们面临的问题并不是找不到算法,而是找到的算法太多了:
image虽然搜索引擎会替我们把一部分完全重复的内容过滤掉,但它的能力毕竟有限。这么多算法看得我们眼花缭乱,到底哪个算法更适合我们呢?我们肯定不可能把所有的算法都试一遍,因为我们根本没有那么多资源和时间。
接下来,我们就需要执行元算法中的第二步:选择算法。也就是从找到的众多算法中,挑选出最适合自己的算法来执行。
我们在前面讲过,一个算法在创造出来之后,在不断地复制传播的过程中,会产生很多的变种。除了算法中最核心的步骤外,其他的一切都可能发生变化。比如 做可乐鸡翅 的算法中必然有“放鸡翅”和“加入可乐”这两步,否则就不再是可乐鸡翅了。然而配菜、调料、烹调时间、烹调方法……可以组成无数种组合,也就形成了无数种大同小异的算法。
只要变种有一定效果,就会流传开来。效果越好的变种,流传就越广。所以别看搜索引擎说它找到了上千万条内容,看起来很吓人,其实那往往只是几十种甚至几种算法变种不断复制传播的结果。
事实上,搜索引擎显示的结果前三页里,基本就包括了所有普遍流行的算法变种。 我们没有必要一直翻到最后一页,看完所有的算法后再作出决定。如果这件事不是特别重要的话,我们完全可以只从第一页里的内容中进行挑选。
比如有一个 制作可乐鸡翅 的算法是这样的:
image材料
鸡翅10只,可乐1瓶,姜,蒜,葱,盐,酱油,老抽,料酒
做法
1、鸡翅洗净,用牙签在鸡翅上扎些小洞
2、姜、蒜、小葱切碎
3、将鸡翅放盘内,再加入切好的姜、蒜、小葱
4、加入盐、酱油、老抽、料酒,用手抓均腌制15分钟
5、锅内倒入食用油小火烧热
6、将腌制好的鸡翅放入锅内,煎到两面呈金黄色
7、加入适量的可乐烧开,可乐和鸡翅持平即可
8、用小火焖至汤汁变浓时即可关火装盘
拿到一个算法后,怎么知道它是不是适合自己呢?我们可以从三个方面进行考察:
1、执行效果: 算法执行的效果如何?我能接受吗? 我们需要知道执行算法后的效果,这样对自己将要付出的时间和精力有个合理的预期。对做可乐鸡翅这个例子来说,几乎每个菜谱都带有效果图,你只要判断图片是否让你有食欲就可以了,感觉不好的直接pass掉。除非已经没有其他选择了,否则不要考虑那些没有说明执行效果的算法。
2、所需条件: 我具备所有的条件吗?我能补足不具备的条件吗?它重要吗? 扫描整个算法,罗列一下执行它需要的条件,比如:材料、技能、时间、金钱……然后逐个检查看自己是不是具备。如果某个条件不具备,我们能不能、愿不愿意付出额外的时间和金钱去交换?在缺失这个条件的情况下执行算法,会出大问题吗?不行的话,那这个算法就只能放弃掉了。比方说你发现家里没有姜,仅仅少一味调料一般来说问题并不大;但是要是没有可乐,你又不能出去买的话,那就别想做可乐鸡翅了。
3、执行难度: 算法是否足够简单?每个步骤描述是否详细?操作起来难吗? 梳理一遍所有的步骤,看看你是否能清楚地明白每一步具体要做什么。算法应该用你能理解的方式来描述和呈现,要是有配图甚至视频则更好。如果算法里面有一大堆你看不懂的专业术语,那这个算法就不太适合你。假如你从来没做过饭,可能对上面那个算法里的一些名词(比如:老抽)有点陌生,或者对某些描述感到疑惑(比如:多大的火算小火?)。如果你不请教一下做饭高手或者在网上搜索来搞明白这些问题,在执行的过程中很可能就会出问题。
你是想追求最好的效果?还是在有限的条件下完成任务?还是想尽可能地保证成功率?哪个对你来说最重要?你需要想明白这一点,然后依此安排考察以上三个方面的顺序,把最重要的放在最前面。 如果最重要的方面出了问题,我们就不需要再浪费时间去考察其他方面了。
把不适合我们的算法都过滤掉之后,往往就只剩下屈指可数的几个选择了。如果你有条件多试几次的话,不妨把它们都保存下来,挨个试一遍。执行过几个不同的算法变种,你就能理解这个算法最核心的部分是什么,各个变种的区别和价值在哪里,甚至可以自己开发出新的变种来。
如果你只有一次尝试机会,那么可以兼顾各个方面,选择综合表现最好的算法;也可以选择在你最看重的那个方面上,单项得分最高的算法(执行效果最好的 / 所需条件最少的 / 执行难度最小的)。
「试一试」
挑一件你从来没做过的事,然后通过搜索引擎来寻找算法。用上面所述的方法,从搜索结果前三页中筛选出适合自己的算法,并确定一个最适合自己的算法,把它保存下来。
5. 怎么做好执行算法前的准备?
在找到合适的算法之后,你可能会觉得胜利已经近在眼前了,接下来只要按照算法一步一步地执行下去,就能完成目标。有点跃跃欲试了吗?
先别着急,请回忆一下,你有没有遇到过下面这些情况?
-
从超市回到家之后,才发现有样东西忘了买
-
为了赶时间匆忙行事,结果不小心把事情搞砸了
-
打游戏时接了个电话,挂断之后游戏已经输掉了
……
俗话说:“预则立,不预则废”。以上列出的问题,都是由于 没有进行充分准备 导致的,也就是说没有做好元算法中的第三步:事前准备。我们在执行算法之前准备得越充分,出问题的可能性就越小。那我们应该怎么做准备呢?
1、制作准备清单
首先,我们应该仔细阅读算法中每一个步骤,想一想:“如果我要执行这一步的话,必须拥有哪些东西?”,然后把所有需要的东西列出一个清单来。千万不要天真地以为,照算法作者列出来的材料清单来做准备就行了。因为作者往往会假设一些东西你肯定有,就没有放在清单里面。比如在做可乐鸡翅的算法中,有这么一步:
image5、锅内倒入食用油小火烧热
很明显,为了完成这一步,你必须要有锅和食用油,而材料清单里并没有。此外想要用火来加热,就还得有燃气灶或者电磁炉。最后,我们可以列出下面的清单来:
材料
鸡翅10只,可乐1瓶,油,姜,蒜,葱,盐,酱油,老抽,料酒
工具
燃气灶 / 电磁炉、锅、铲子、菜刀、案板、盘子、牙签
如果不经过特殊的训练的话,我们的大脑只能同时记住三到五件事情,当有新的事情需要记忆时,之前的事情就会被忘掉。所以我们一定要把清单记录在可靠的媒介上,比如抄到纸上或者存在手机里,不要相信自己的记忆!
2、按照清单进行准备,多多益善
接下来,我们就可以按照清单来做准备工作了。把缺少的东西标记出来,然后去超市统一采购。如果有样东西在超市买不到,那就在网上买,也可以问别人借。除此之外,对已经有的东西最好也检查一下,看看数量够不够、能不能用、有没有损坏……每当你 做好了一项准备,就在清单上做一个标记(比如打勾或者划掉)。
image算法越复杂、需要准备的东西越多,出现各种意外的可能性就越大。假如你在拿可乐时不小心摔了一跤,一瓶可乐全倒在了地上怎么办?所以 不管是材料、时间还是金钱,都应该尽可能多准备一些。 就算只需要一瓶可乐,也最好买上两瓶,剩下了还可以自己喝。如果你计划一个小时完成,那么至少要准备上两三个小时,万一发现少了什么东西还可以再去超市买一次……
准备完成之后,千万别忘了 再对照清单核对一遍!
3、调整环境和自我状态
为了更好地执行任务,我们还需要 调整好自己的身体状态。每个人都有不同的生理节奏,有的人早上精力充沛,而有的人到了晚上注意力才能集中起来。越是重要的事,越要安排在自己状态最好的时候来做。比如刚刚吃完饭人很容易犯困,这时候就不太适合执行需要认真思考的任务。而在开始高强度运动之前,则必须做适量的热身来让身体做好准备,以避免受伤。
此外,创造一个免受外界打扰的环境 也是很有必要的。因为只有集中精力,才能把事做好。假如你正在玩对战游戏,那么最讨厌的事莫过于来电话了。如果你不得不接这个电话,那么很可能会心不在焉,一直想着游戏里的事。等电话挂掉,游戏往往也已经输掉了。这种体验真让人沮丧,对吗?
为了避免外部干扰,我们可以在执行算法之前,把手机关机或者调成静音、锁上房门或者挂上“请勿打扰”的牌子、去咖啡厅或者图书馆……
最后,如果你没有任何相关领域的经验,那么最好能 找一位专业人士在旁指导。因为只要是人都会犯错误,专业人士不仅可以在你出现问题时及时纠正,也能在你碰到各种意外情况时,提供有效的帮助,避免出现无法挽回的局面。
image如果实在找不到有经验的人,也最好能找一个信得过的伙伴来一起做。犯错误并不可怕,只要及时发现,采取有效的措施来补救即可。真正可怕的是犯了错而不自知,等到发现后为时已晚。更可怕的是明知道自己犯了错误,还要一意孤行,往往会酿成大错。
如果我们做好了充分准备,提前考虑到了各种意外情况,那么在执行算法时心里就会更有底气,也就更可能取得好的效果。
「试一试」
选择一个自己从来没有执行过的算法,然后用上面所述的方法来做好执行前的准备工作
(未完待续)