动态规划
来源:互联网 发布:淘宝如何买发票 编辑:程序博客网 时间:2024/04/27 05:01
[概念]
1,和贪婪算法一样,在动态规划中,可将一个问题的解决方案视为一系列决策的结果。不同的是,在贪婪算法中,每采用一次贪婪准则便做出一个不可撤回的决策,而在动态规划中,还要考察每个最优决策序列中是否包含一个最优子序列。
2,当最优决策序列中包含最优决策子序列时,可建立动态规划递归方程(recurrence equation),它可以帮助我们高效地解决问题。根据我的理解,这个递归方程是整个动态规划问题的核心:如果可以制作递归方程,那么基本上就是可解的;如果不能构造出递归方程,则很难对这个问题实施可行性的解。
3,动态规划方法采用最优原则( principle of optimality)来建立用于计算最优解的递归式。所谓最优原则即不管前面的策略如何,此后的决策必须是基于当前状态(由上一次决策产生)的最优决策。由于对于有些问题的某些递归式来说并不一定能保证最优原则,因此在求解问题时有必要对它进行验证。若不能保持最优原则,则不可应用动态规划方法。在得到最优解的递归式之后,需要执行回溯以构造最优解。
4,使用递归程序来求解动态规划递归方程的时候,如果不避免重复计算,递归程序的复杂性将非常恐怖。所以,希望能够在递归程序设计中解决重复计算,或者使用迭代方式来求解,自然地避免了重复计算。如果没有了重复计算,复杂性将急剧下降。尽管迭代程序与避免重复计算的递归程序有相同的复杂性,但迭代程序不需要附加的递归栈空间,因此将比避免重复计算的递归程序更快。
[具体案例]
1,最短路经
a, 有向图,要寻找一条从源节点s= 1到目的节点d= 5的最短路径,即选择此路径所经过的各个节点。
b, 解释:最短路径问题中,假如在第一次决策时到达了某个节点v,那么不管v 是怎样确定的,此后选择从v 到d 的路径时,都必须采用最优策略。
2,0/1背包问题
a, 如前所述,在该问题中需要决定x1 .. xn的值。假设按i = 1,2,.,n 的次序来确定xi 的值。如果置x1 = 0,则问题转变为相对于其余物品(即物品2,3,.,n),背包容量仍为c 的背包问题。若置x1 = 1,问题就变为关于最大背包容量为c-w1 的问题。现设r={c,c-w1 } 为剩余的背包容量。
b, 解释:在这个问题中,第i个元素的值的选择(0或者1),不会影响后续n-i个元素的解;另外,刨除i之后,后面n-i个元素的最优解,必定是构成整个解的最优解的一部分。
c, 递归方程:
f(n,y) = p(n), if y>=w(n);
or = 0, if y<w(n);
f(i,y)= max(f(i+1, y), f(i+1,y-w(i)) + p(i), if y>=w(i);
or = f(i+1,y), if y<w(i);
根据这个递归方程,很容易就能构造出来一个递归的代码(没有验证和调试):
- int f(int i, int j)
- {
- if (i == n) return (y < w[n]) ? 0 : p[n];
- if (y < w[n]) return f(i+1, y);
- return max(f(i+1,y), f(i+1, y-w[i]) + p[i]);
- }
3,航费
4,图像压缩
5,所有点对的最短路径
6,矩阵乘法链
a, 一个m×n矩阵A与n×p矩阵B相乘需耗费O(m*n*p)的时间。(A*B) *C和A* (B*C) ,尽管这两种不同的计算顺序所得的结果相同,但时间消耗会有很大的差距。
b, 使用动态规划的方法,会期望把性能降低到O(q^3),q是矩阵个数。
c, 递归方程:
c(i,i) = 0 --> 1<=i<=q; c保存的是费用;
c(i, i+1)=r[i]*r[i+1]*r[i+2], 同时, kay(i, i+1) = i; --> 1<=i<=q;
c(i, i+s) = min(c(i, k) + c(k+1, i+s) + r[i]*r[k+1]*r[i+s+1], --> 1<=i<=q-s, 1<s<q; k属于[i, i+s)累计
kay(i,j)保存的事从i到j中能够得到最小K的数据;
[矩阵乘法链代码]
- const int SIZE = 6;
- // matrix row and cols
- int r[SIZE] = {10, 5, 1, 10, 2, 10};
- // matrix mult order
- int kay[SIZE][SIZE] = {0};
- // avoid re-computing for cost
- int c[SIZE][SIZE] = {0};
- // calculate the min cost of:
- // M(i,k) X M(k,j)
- int cost(int i, int j)
- {
- if ( c[i][j] > 0) //avoid re-computing for cost
- return c[i][j];
- if (i == j) // M(ii) need no time
- return 0;
- if (i == (j - 1)) { // M(i,i) X M(i+1,i+1) need: r(i)*r(i+1)*r(i+2)
- kay[i][j] = i;
- return c[i][j] = r[i]*r[i+1]*r[j+1];
- }
- // more than 2 matrices for mult
- // set min u
- int u = cost(i, i) + cost(i + 1, j) + r[i]*r[i+1]*r[j+1];
- kay[i][j] = i;
- // compute the remain min term
- for ( int k = i + 1; k < j; k++) {
- int temp = cost(i, k) + cost(k + 1, j) + r[i]*r[k+1]*r[j+1];
- if ( temp < u ) {
- u = temp;
- kay[i][j] = k;
- }
- }
- c[i][j] = u;
- return u;
- }
- // print result
- void printResult(int i, int j)
- {
- if ( i == j )
- return;
- printResult(i, kay[i][j]);
- printResult(kay[i][j] + 1, j);
- printf("Multiply M[%d,%d]", i, kay[i][j]);
- printf(" and M[%d,%d]/n", kay[i][j] + 1, j);
- }
- // test
- int main(int argc, char* argv[])
- {
- cost(0, SIZE - 2);
- printResult(0, SIZE - 2);
- getchar();
- return 0;
- }
[其他]
待扩展
- 动态规划!!!动态规划!!!
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 中山大学2009年硕士研究生招生院(系)通讯录
- Voice Quality Test 基本概念介绍
- 怎么直接建立一个DataTable并且为之添加数据
- 什么都不简单
- エラー「APP-FND-00222」
- 动态规划
- 手动创建DataTable并绑定gridview
- 关于临时表和存储过程返回结果
- MOSS搜索引擎各版本功能区别
- lucene 基本使用
- 转载:一位软件工程师工作6年的总结
- 定时刷新客户端的两种方法
- 代友招聘互联网媒体方向的产品经理
- JPEG格式(JPEG File Interchange Format)