如何培养算法直觉?

20
当我面对软件问题时,通常我会立即看到解决方案。当然,我所看到的通常有些偏差,我总是需要坐下来设计(诚然,我通常不够充分地设计),但我立即有一定的直觉。
我的问题是,当涉及高级算法时,我没有获得同样的直觉。相比构建另一个 Facebook,构建另一个 Google 搜索或 Music Genom project,我感觉更能胜任前者。这可能是因为我已经建造软件相当长一段时间了,但我在组合算法方面缺乏经验。
我想听听社区的建议,了解应该阅读什么和承担哪些项目,以便更好地组合算法。
(这个问题与Algorithmic composition几乎没有关系。)
6个回答

11

谁说经验是最好的老师,给他点个赞。

有几个在线门户网站可以提供许多编程问题,您可以提交自己的解决方案并获得自动的通过/失败指示。

  1. http://www.spoj.pl/
  2. http://uva.onlinejudge.org/
  3. http://www.topcoder.com/tc
  4. http://code.google.com/codejam/contests.html
  5. http://projecteuler.net/
  6. https://codeforces.com
  7. https://leetcode.com

美国信息学奥林匹克培训网站是所有美国计算机奥林匹克参赛者都必须接受的培训计划。它会逐步介绍越来越复杂的算法。


10

您可能会发现将算法进行物理演练会更有帮助。例如,在学习排序算法时,可以使用一副纸牌来实践每个算法。这将激活不同于仅阅读或编程的大脑部分。


8

Steve Yegge在他的一篇抨击文章中提到了"算法设计手册"。我自己没有看过,但从他的描述来看,它似乎是非常有用的。

我个人最喜欢的面试准备书籍是Steven Skiena的《算法设计手册》。与其他任何一本书相比,它更能帮助我理解图形问题是多么普遍(和重要)-它们应该成为每个工作程序员的工具包的一部分。该书还涵盖了基本数据结构和排序算法,这是一个不错的奖励。但是金矿是该书的后半部分,它是关于数以亿计有用问题和各种解决方法的百科全书,没有太多细节。几乎每个页面都有简单的图片,使其易于记忆。这是学习如何识别数百种问题类型的好方法。


5

问题领域

首先,您必须了解问题领域。对错误问题的优雅解决方案并没有什么用,对大多数情况下正确问题的低效解决方案也没有用处。换句话说,解决方案的质量通常是相对的。一个简单的调度问题,如果每周重新计算一次,则具有确定性解决方案并需要花费十分钟运行可能没有问题,但是如果调度每天更改几次,则可能需要收敛于几秒钟的基因算法解决方案。

分解和映射

其次,将问题分解为子问题和对应于解决方案元素的已知/未知元素。有时这是很明显的,例如,要计算小部件数量,您需要一种识别小部件的方法、可递增的计数器和一种存储计数的方式。有时则不是那么明显。有时您必须同时分解问题、领域和可能的解决方案,并尝试多个不同的映射,以找到导致正确结果的映射 [这是一般方法]。

建模

至少在脑海中对解决方案进行建模,并通过其进行步进式检查以确保其正确性。根据需要进行调整(请参阅上面的分解和映射)。

组成/接口

许多时候,你可以找到问题的元素和解决方案的元素相互映射并产生有用的部分结果。这种组合和接口构造提供了解决方案的核心,并有助于减少剩余问题的范围。因此,您只需使用较小的初始问题回到顶部,然后再次进行操作。
经验
当然,经验是最好的老师,但阅读有关不同类型问题和解决方案的资料也会很有帮助。学习一些著名算法及其应用也非常有帮助,例如DijkstraBresenhamUnification,当然还有图论

0
我不确定直觉是否可以培养,但我知道你在问什么。解决的问题越多,你就会拥有更多的信息和经验,以便应对未来的问题。所以,我建议只要多练习。练习编写真实世界的应用程序,你就会遇到很多问题。有时候,解决难题也可以非常有教育意义。

0

当我面对一个复杂的问题时,我会尝试寻找物理类比。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接