1.动态规划的起源
- 动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。 20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时,提出了著名的最优化原理(principle of optimality),把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法——动态规划。 1957年出版了他的名著Dynamic Programming,这是该领域的第一本著作
2.动态规划的应用领域
- 领域
生物信息学(Bioinformatics).
控制论(Control theory).
信息论(Information theory).
运筹学(Operations research).
计算机科学,图形处理,语音处理 ,AI, …. - 一些常见的动态规划算法.
Viterbi 隐马尔科夫模型.
Unix 中diff 用于比较两个文件的不同.
序列对比中Smith-Waterman 算法.
网络中最短路径算法Bellman-Ford
……
3.算法的总体思想
- 动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题
- 但是经分解得到的子问题往往不是互相独立的。不同子问题的数目常常只有多项式量级。
在用分治法求解时,有些子问题被重复计算了许多次。
与分治递归方法的区别: 分治递归方法经分解得到的子问题往往是互相独立的
- eg:Fibonacci 数列
Fibonacci 数列:
1, 1, 2, 3, 5, 8, 13, … … … …
用分治递归的代码实现如下:
public static int fibonacci(int n)
{
if (n <= 1)
return 1;
return fibonacci(n-1)+fibonacci(n-2);
}
- eg:合并排序,算法mergeSort的递归过程。
利用分治递归思想,各个子问题 是独立的
4.动态规划的关键思想
-
用递归算法进行设计,很多子问题重复计算,无形的增加了算法的计算量
-
如何减少子问题的重复计算是动态规划算法的关键解决思想
关键思想就是:如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。
这些独立的子问题,在每次计算之后都将其保存起来,后来在用到子问题的答案时,查询一下, 不用其重复的计算 -
eg:减少下面图中,红色子问题的计算
5.动态规划的基本步骤
- 找出最优解的性质,并刻划其结构特征。(寻找最优解的子问题结构)
- 递归地定义最优值。(根据子问题结构建立问题的递归解式求解最优值)
- 以自底向上的方式计算出最优值。(动态规划思想)
- 根据计算最优值时得到的信息,构造最优解。