动态规划和子结构的浅谈

1 def fib(n):
2     global numCails
3     numCails +=1
4     print "numCails-->",numCails
5     print "n---->",n
6     if n <=1:
7         return n
8     else:
9         return fib(n-1) + fib(n-2)

我们先看看之前的代码。这是一个 斐波那契数列 我们知道这个代码的执行会有很多重叠的子结构。

让我们先看下图{我今天不用笔画了 LOL}

{感谢ProcessOn,我也能画个能看的图了}

我们从上图看到 产生和很多重叠的子结构,重复运算了很多已经算过了,这就比较尴尬了。

这个时候我们要提下动态规划了:

{个人----理解}
动态规划:动态规划是一种思维方法,也是一种优化原理。优化思路:通过保存那些已经求过值的状态,来避免相同子结构的出现

猿爸爸把 1+1+1+1+1+1+1+1 = 写在纸上,问小猿(咦):

「它们加起来是多少哇?」
(数了一会…)「8 !」
猿爸爸在左边又加了个 1+,再问一次小猿:
「现在呢?」
(迅速地)「9 !」
「为什么小猿这么快就知道了呢?」

「因为你刚刚加了 1 啊~」

「所以只要记得之前的结果,就不用再计一次数啦。」

嗯,动态规划就是一种「先记住些事,方便后面节约时间」的神奇方法

{真是 so easy啊}

我们在看改进过后的代码

 1 def fib2(n,memo):
 2     global numCalls
 3     numCalls += 1
 4     print "--->",n
 5     if not n in memo:
 6         memo[n] = fib2(n-1,memo)+fib2(n-2,memo)
 7     return memo[n]
 8 def fib1(n):
 9     memo = {0:1,1:1}
10     return fib2(n,memo)
11 numCalls = 0
12 print fib1(6)

我们把执行结果都存到memo中,然后每次执行前都看下是不是在memo中。这样也是一种牺牲空间换取时间的做法,但是我们要知道,我们这样做避免了一次指数级的运算

这就是所谓的动态规则。它适用于,获得最优子机构的时候,局部解决方案有重叠的时候。

posted @ 2016-07-06 01:21  nerdlerss  阅读(405)  评论(0编辑  收藏  举报