提高算法思维能力

48

我在思考如何提高自己解决问题的算法能力。我想到可以从各种数学领域的问题中寻找解决方法,比如离散数学或线性代数。在谷歌上搜索了一会儿后,我读到了一篇文章,声称需要学习游戏编程才能达到这个目标,这对我来说似乎很合理。

你是否跟我有同样的疑虑,或者你有什么想法呢?期待听到你的回复。

提前感谢大家。

P.S.1:我想说,我已经知道编程和如何编程(虽然我只是一个业余爱好者 :-)),我只是想在特定问题上提高,而不是开始学习它。

P.S.2:我认为这是一个有用的话题,以备将来参考,因此我勾选了社区 wiki。

13个回答

52
每天解决问题。观察交通灯,问自己:“如何同步它们以优化交通流?或者优化行人流量?两者的最佳解决方案是什么?”看着电梯,问自己:“为什么这些电梯应该使用不同的规则,而不是我昨天参观的那栋楼里的电梯?它是如何实现的?可以如何改进?”
尝试在任何地方看到问题,即使问题已经得到解决。反思解决方案。问自己为什么你自己的优秀解决方案可能不如你所看到的解决方案好-你漏掉了什么?
等等。每一天。所有时间。
想法是几乎任何事情都可以被视为算法(对某人有某种意义的目标,以及实现该目标的方法)。下次看电视上的游戏节目,或者阅读最新银行抢劫的新闻报道时,请记住这一点。问自己:“目标是什么?”,“目标属于谁?”和“方法是什么?”
这很容易被误认为是批判性思维,但更多的是质疑自己的解决方案,而不是你试图理解和改进的解决方案。

13
如果你做得正确,这将变得自动化,会让你的朋友和亲人感到非常恼火。=) (+1) - Erik Forbes
我非常喜欢这个解决方案。 - deeb
2
@Erik:有点像在注塑公司工作,然后意识到桌子上的其他人对塑料叉子上的弹出销不感兴趣。 - David Thornley
这是一个很棒的回答:我已经做了很长时间,这确实帮助了我。 - DivineWolfwood

30

首先,最重要的是实践。每次都要想出各种解决方案。它不一定在你的电脑上编程。所有算法都会很好地发挥作用。就像这样:当你玩交易卡片时,你如何比较你的牌组和你朋友的牌组,以确定你们两个交易的最佳方式?你如何定义你能做多少次交易才能达到最大化,而又不会得到任何重复卡片呢?

使用问题数据库和在线评测网站,例如这个网站 http://uva.onlinejudge.org/index.php,该网站拥有数百个有关通用算法的问题。你完全不需要成为专业程序员就可以解决其中任何一个问题。你所需要的是良好的逻辑和数学能力。在那里,您可以找到从简单到最具挑战性的问题。其中大多数来自编程马拉松比赛。

然后,您可以使用C、C++、Java或Pascal将它们实现,并将其提交给在线评测网站。如果您有一个好的算法,它将被接受。否则,评测系统将告诉您的算法给出了错误的答案或者计算时间太长。

阅读有关算法的资料是有帮助的,但不要浪费太多时间...阅读并不像自己尝试解决问题那样有用。也许您可以先阅读问题,尝试自己想出一个解决方案,然后将其与源提供的解决方案进行比较,看看您错过了什么。不要试图记住这些解决方案。如果你已经学会了这个概念,你可以在任何地方实现它。理解对于大多数人来说是最难的部分。


12

Polya的《如何解决它》是一本思考如何解决数学问题和证明的好书,我建议任何从事问题解决的人都应该阅读。

但是!它并没有真正涉及当现实世界通过信道噪声、用户反常行为、其他程序抓取资源等方式向你的系统提供输入时所产生的刺激。为此,值得查看应用于真实世界输入的算法(Knuth收集的必要而应得的致敬),以及在面对同样情况时相当强大的系统(TCP、内核内部)。想要提出良好的算法解决方案的一部分就是要知道已有的解决方案。

当然,在阅读所有这些文章的同时,也需要不断地实践实践实践


嘿,练习是好的!我同时发布了一个类似的答案。他们说伟大的思想会想到一起,对吧?(你知道的,平庸的人也会 ^_^) - weiji

8
你应该看一下G. Polya的《数学与合理推理》。这是一本罕见的数学书,实际上涉及到了在进行数学发现时所涉及的思维过程。我认为这与提出算法所涉及的思维过程相同。

5
这句谚语“熟能生巧”绝对是适用的。我正在辅导我的一个编程朋友,我提醒他,“如果你不知道如何骑自行车,你可以阅读关于它的所有书籍,但这并不意味着你明天就能比兰斯·阿姆斯特朗更好 - 你必须实践。”
对于你来说,试试Project Euler上的问题怎么样?http://projecteuler.net
那里有很多问题,每个问题都可以练习开发算法。一旦你得到足够好的实现,你可以访问其他人的解决方案(针对特定问题),看看别人是如何做到的。不要把它看作数学问题,而应该看作是解决数学问题的算法问题。
在大学里,我实际上修了一门算法设计与分析课程,它确实有很多理论知识。你可能会听到人们谈论“大O”复杂度之类的东西 - 关于算法本身的很多不同属性可以带来更深入的理解,以确定什么构成了“好”的算法。你也可以从这方面进行相当多的学习,以便长期受益。

关于算法本身有很多不同的属性,这些属性可以带来更深入的理解,从而确定什么是“好”的算法。但实际上并没有那么多属性,主要包括:1 速度,2 最低资源使用,3 优雅,4 简洁。换句话说,就是“紧凑”。 - ocodo

5

4
我建议你按照以下步骤进行:
1.首先学习语言的基本部分。
2.然后学习一些基本数学知识。
3.开始尝试topcoder div2简单问题。通常,如果您在任何一天无法得分250,则说明需要大量练习,请继续练习。
4.现在是学习编程工具的时候了,请参考Steven Skienna的《算法设计手册》,学习动态规划和贪心算法。
5.现在开始参加马拉松比赛,如果你不能很快解决问题不要灰心丧气。提高不会一夜之间发生,您需要耐心地继续努力。
6.从现在开始继续第5步,您会成为更好的程序员。

Topcoder是一个好主意 :) - py_script

3
学习游戏编程可能会带领你掌握好的游戏编程算法,但不一定能够让你掌握更好的通用算法。
这是一个良好的开始,但我认为学习和应用算法知识的最佳方式是:
1. 学习目标领域中已经存在的好的算法。 2. 扩展你的知识范围,了解其他领域;例如,在进行基因分析时需要哪些算法?在涉及洪水时,确定径流潜力的最佳方法是什么? 3. 阅读其他领域的问题,并尝试使用你熟悉的算法来解决。如果不行,尝试将问题分解并思考是否可以提出自己的算法。

游戏编程有助于一般算法思维的原因相当广泛。 1. 广义而言,问题领域很大,通常只受想象力限制,不仅限于面对特定行业的问题。 2. 通常会寻求最优解,而不是将其视为美好的愿望(即通常完成工作并不足够,通常需要快速完成)。 3. 在这个领域,你的同行会非常有竞争力,你会比写典型的业务或企业应用程序的人学到更多/“锻炼”更多。 - ocodo

2

以下是几本值得阅读的书籍(无特定顺序):

  • Aha! Insight(马丁·加德纳)
  • 任何一本编程珠玑系列书籍(乔恩·本特利)
  • 具体数学(格雷厄姆,库努斯和帕塔什尼克)
  • 通信的数学理论(克劳德·香农)

当然,这些只是样本--同一作者的其他书籍和论文通常也非常好(例如,香农写了很多值得阅读的内容,但关注它的人太少了)。


1

非常好,不妨尝试Project Euler中的问题?http://projecteuler.net

那里有很多问题,对于每个问题,您都可以练习开发算法。一旦您获得了足够好的实现,就可以访问其他人的解决方案(针对特定问题),并查看其他人是如何做到的。不要把它看作数学问题,而是看作为解决数学问题创建算法的问题。


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