正文

动态规划--维基百科2009-09-17 19:33:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/shao/47851.html

分享到:

 

http://zh.wikipedia.org/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92

 

动态规划是一种在数学和计算机科学中使用的,用于求解包含重叠子问题的最优化问题的方法。其基本思想是,将原问题分解为相似的子问题,在求解的过程中通过子问题的解求出原问题的解。动态规划的思想是多种算法的基础,被广泛应用于计算机科学和工程领域。比较著名的应用实例有:求解最短路径问题,背包问题,项目管理,网络流优化等。
目录 [隐藏]
1 概述
2 步骤
3 实例
3.1 斐波那契数列
3.2 背包问题
4 使用动态规划的算法
5 外部链接


[编辑] 概述
动态规划在查找有很多重叠子问题的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间。
动态规划只能应用于有最优子结构的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。
[编辑] 步骤
最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。
[编辑] 实例
[编辑] 斐波那契数列
计算斐波那契数列的一个最基础的算法是,直接按照定义计算:
   function fib(n)
       if n = 0 or n = 1
           return 1
       return fib(n − 1) + fib(n − 2)
当n=5时,fib(5)的计算过程如下:
fib(5)
fib(4) + fib(3)
(fib(3) + fib(2)) + (fib(2) + fib(1))
((fib(2) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1))
(((fib(1) + fib(0)) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1))
由上面可以看出,这种算法对于相似的子问题进行了重复的计算,因此不是一种高效的算法。实际上,该算法的运算时间是指数级增长的。 改进的方法是,我们可以通过保存已经算出的子问题的解来避免重复计算:
array map [0...n] = { 0 => 0, 1 => 1 }
fib( n )
    if ( map( n ) is cached )
        return map( n )
    return map( n ) = fib( n - 1 ) + fib( n - 2 )
将前n个已经算出的前n个数保存在数组map中,这样在后面的计算中可以直接易用前面的结果,从而避免了重复计算。算法的运算时间变为O(n)
[编辑] 背包问题
背包问题作为NP完全问题,暂时不存在多项式时间算法。动态规划属于背包问题求解最优解的可行方法之一。此外,求解背包问题最优解还有搜索法等,近似解还有贪心法等,分数背包问题有最优贪心解等。 背包问题具有最优子结构和重叠子问题。动态规划一般用于求解背包问题中的整数背包问题(即每种物品所选的个数必须是整数)。 解整数背包问题: 设有n件物品,每件价值记为Pi,每件体积记为Vi,用一个最大容积为Vmax的背包,求装入物品的最大价值。 用一个数组f[i,j]表示取1-i件商品填充一个容积为j的背包的最大价值,显然问题的解就是f[n,Vmax].
f[i,j]=
      f[i-1,j] {j<Vi}
      max{f[i-1,j],f[i,j-Vi]+Pi {j>=Vi}
      0 {i=0 OR j=0}
对于特例01背包问题(即每件物品最多放1件,否则不放入)的问题,状态转移方程:
f[i,j]=
      f[i-1,j] {j<Vi}
      max{f[i-1,j],f[i-1,j-Vi]+Pi {j>=Vi}
      0 {i=0 OR j=0}
[编辑] 使用动态规划的算法
最长单调子序列
最长公共子序列
Floyd-Warshall算法
Viterbi算法

阅读(1686) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册