1、动态规划算法介绍
基本思想是将待求解问题分解成若干子问题,先求解 子问题,最后用这些子问题带到原问题,与分治算法的不同是,经分解得到的子问题往往是不是相互独立,若用分治则子问题太多。
2、适用动态规划算法问题的特征
a、优化原则。具有最优的子问题.或者说一个最优决策序列的任何子序列本身一定是相对于子序列的初始和结 束状态的最优的决策序列。
b、子问题重叠性质。一般情况是子问题不能独立,需要多次计算。
3、一般的步骤
a、将问题表示成多步判断。
b、确定是否满足优化原则,确定子问题的重叠性。
c、列出关于优化函数的递推方程(或不等式)和边界条件。
d、自底向上计算子问题的优化函数值。
e、备忘录方法记录中间结果。在算法实现上是从低往上的,这点和分治算法不同。
f、标记函数追踪问题的解。
4、举例
投资问题:
m元钱,n项投资,fi(x): 将x元投入第i项项目的效益,
目标函数max {f1(x1) + f2(x2) + … + fn(xn) }
约束条件x1 + x2 + … + xn = m,xi ∈ N
设Fk(x) 表示x元钱投给前k个项目的最大效益
多步判断: 假设知道p元钱(p≤x)投给前k −1个项目的最大效益,决定x元钱投给前k个项目的分配方案
递推方程和边界条件:
Fk(x) = max{fk(xk)+Fk-1(x-xk)}
F1(x)=f1(x)
算法实现
投资第k个项目p元钱的效益可表示为Project[k][p],其中0<=k<=n,0<=p<=m;设投资给前k个项目p元 钱的最终总效益为用Benefit[k][p],其中0<=k<=n,0<=p<=m。设allot[k][p]表示在总投资为p元钱时候,最终分配给第k个项目的钱数解。
算法如下:
for(k=0 ; k<= n ;i++)
{
for(p=0 ; p<= m ;p++) //开始从低往上计算k个项目、总投资为p元情况下的效益
{
Benefit[k][p] = 0;
allot[k][p] = 0;
for(x=0; x<=p ;x++) //遍历p元钱分配情况:x和p-x,取出一个最大值
{
if( Benefit[k][p]<( Benefit[k-1][x] + project[k][p-x]))
{
Benefit[k][p] = Benefit[k-1][x] + project[k][p-x];
allot[k][p] = x;
}
}
}
}
最后方便得出效益:Project[k][p],
其中allot[1][p]、allot[2][p].....allot[k][p]便是对应的项目解,也就是投资给每个项目的钱数。
算法分析:w(n)=O(nm2),算法需要较大的辅助空间。
阅读(5455) | 评论(3) | 转发(0) |