动态规划法
动态规划是考察问题的一种途径,或是求解某类问题 的一种方法。
动态规划问世以来,在经济管理、生产调度、工程技 术和最优控制等方面得到了广泛的应用。例如最短路 线、库存管理、资源分配、设备更新、排序、装载等 问题,用动态规划方法比其它方法求解更为方便。
6.1.1 多阶段决策过程
问题的解由该问题的n个输入的一个子集组成,这个 子集必须满足某些事先给定的条件,这些条件称为约 束条件。
状态既是该阶段的某个起点,又是前一个阶段的某个 终点。通常一个阶段有若干个状态。
状态无后效性:如果某个阶段状态给定后,则该阶 段以后过程的发展不受该阶段以前各阶段状态的影 响,也就是说状态具有马尔科夫性。
适于动态规划法求解的问题具有状态的无后效性。
策略:各个阶段决策确定后,就组成了一个决策序列, 该序列称之为一个策略。
满足约束条件的解称为问题的可行解。
衡量所有可行解的优劣,通常以函数的形式给出一定 的标准,这些标准函数称为目标函数(或评价函数)。
使目标函数取得极值(极大或极小)的可行解称为最 优解。
具有上述这些要素的问题称为最优化问题。
例如:在0/1背包问题中,物品i或者被装入背包, 或者不被装入背包,设xi表示物品i装入背包的情 况,则
对于1≤i≤j≤n不同的有序对(i,j),对应于不同的子 问题。因此,不同子问题的个数最多只有
Cn2
n 2
n
(n2
)
因此,求解此问题可依据递归关系式以自底向上的方
式进行计算。在计算过程中,保存已解决的子问题
答案。
另外开辟存储空间
计算最优值的算法描述:
void MatrixChain(int *p,int n,int **m,int **s) { //数组p存储各矩阵的维数;n是矩阵个数
输出:数塔的最大数值和及其路径
1. 初始化数组maxAdd的最后一行为数塔的底层数据:
for (j = 0; j < n; j++)
T(n)=O(n)
maxAdd[n-1][j] = d[n-1][j];
2. 从第n-1层开始直到第 1 层对下三角元素maxAdd[i][j] 执行下述操作:
2.1 maxAdd[i][j] = d[i][j] + max{maxAdd[i+1][j], maxAdd[i+1][j+1]};
递归地定义最优值。(确定动态规划函数)
——建立递归关系式
以自底向上的方式计算出最优值。 根据计-1:数塔问题。
【问题描述】从数塔的顶层出发,在每一个结点可 以选择向左走或向右走,一直走到最底层,要求找 出一条路径,使得路径上的数值和最大。
?8 ?
12 15
由某个阶段开始到终止阶段的过程称为子过程,其对 应的某个策略称为子策略。
一个决策序列在不断变化的状态中产生,这个决 策序列产生的过程称为多阶段决策过程。
S0
P1
S1
P2
S2
Sn-1
Pn
Sn
最优性原理:无论决策过程的初始状态和初始决
策如何,其余的决策都必须相对于初始决策所产
生的当前状态,构成一个最优决策序列。
3 96
8 10 5 12
16 4 18 10 9
分析:
8 12 15 3 96 8 10 5 12 16 4 18 10 9
求解初始子问题:底层的每个数字可以看作1层数塔,则
8
最大数值和就是其自身;
12 15 3 96
再求解下一阶段的子问题:第4层的决策是在底层决策的 基础上进行求解,可以看作4个2层数塔,对每个数塔进行 求解;
m[2][4] m[5][5] p1 p4 p5 4375 0 3510 20 11375
⑷ 构造最优解 依据MatrixChain算法中数组s[i][j]记录的信息,可以
确定计算矩阵链A[i:j]的最佳方式应该在矩阵Ak和 A(Ak+[i1:之k]间)(A断[k开+1,:j]即)。最因优此加,括递号归的地方构式造应最为优解: void Traceback (int i, int j, int **s) { if (i==j) return; Traceback(i, s[i][j], s); Traceback(s[i][j]+1, j, s); cout<<“Multiply A”<<i<<“,”<<s[i][j]; cout<<“and A”<<(s[i][j]+1)<<“,”<<j<<endl; }
初始子问题
原问题
A
B
C
D
E
多阶段决策过程
——最优子结构性质(或优化原则)
6.1.3 算法总体思想
与分治法类似,动态规划算法的基本思想也是将待求解问 题分解成若干个子问题,但是经分解得到的子问题往往不 是互相独立的。
保存已解决的子问题的答案,需要时再找出已求得的答案, 就可以避免大量重复计算,从而得到多项式时间算法。
(全A加((B括C号)D的))矩阵连( A乘(B积(CBD和))C)的乘((积AB并)(加CD括)号) ,即 (A(=(A(BBC)C)。)D) ((A(BC))D)
16000, 10500, 36000, 87500, 34500
如何确定计算矩阵连乘积的计算次序,使得依此次 序计算矩阵连乘积需要的数乘次数最少。
T(n) =
n
n/2
n/2
n/2
n/2
T(n/4) T(n/4) T(n/4) T(n/4) T(n/4) T(n/4) T(n/4) T(n/4) T(n/4) T(n/4) T(n/4)
动态规划算法适用于解最优化问题。步骤:
找出最优解的性质,并刻划其结构特征。(划分子 问题)
最优子结构性质:问题的最优解包含其子问题的最 优解。 ——显著特征
乘的,i 1,2,...,n 1 。考察这n个矩阵的连乘积
A=A1A2... An
矩阵连乘的计算次序可以用加括号的方式来确定。 设因有此四,个矩完阵全,加它括们号的的维矩数阵分连别乘是积:可递归地定义为:
A 单5个0矩1阵0 是B完1全0加4括0号C的;4030 D 305
总共 有矩五阵中连完乘全积加A是括完号全的加方括式号:的,则A可表示为2个完
例如:付款问题——超市的自动柜员机(POS机) 要找给顾客数量最少的现金。
分析:假定POS机中有n张面值为pi(1≤i≤n)的货币,用
集合P={p1, p2, …, pn}表示,若POS机需支付的现金为A, 则必须从P中选取一个最小子集S,使得
m
pi S , pi A (m | S |) (式6.1) i 1
8 10 5 12 再求解下一阶段的子问题:第3层的决策是在第4层决策的 基础上进行求解,可以看作3个2层的数塔,对每个数塔进
16 4 18 10 9 行求解;
以此类推,直到最后一个阶段:第1层的决策结果就是数 塔问题的整体最优解。
值,
算法描述:
复杂度分析
输入:二维数组d[n][n]
T(n)=O(n2)
复杂if 度(t <分m析[i][j]) { m[i][j] = t; s[i][j] = k;}
}算法matrixChain的主要计算量取决于算法中对r,i }和k的3重循环。循环体内的计算量为O(1),而3重循环 } 的总次数为O(n3)。因此算法的计算时间上界为O(n3)。 算法所占用的空间显然为O(n2)。
m[i][j] = m[i+1][j]+ p[i-1]*p[i]*p[j]; s[i][j] = i; //初始化矩阵链的断开位置
for (int k = i+1; k < j; k++) { //求最优值(即最少数乘次数),并记录断开位置
int t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
xi=0时,表示物品i没有被装入背包, xi=1时,表示物品i被装入背包。 根据问题的要求,有如下约束条件和目标函数:
n
wi xi C
i 1
xi {0,1} (1 i n)
n
max vixi i1
6.1.2 最优化问题
最优化问题的求解可以划分为若干个阶段,每一 阶段的决策仅依赖于前一阶段的状态,由决策所 采取的动作使状态发生转移,成为下一阶段决策 的依据。
i≤k<j,则其相应完全加括号方式为
( Ai Ai1... Ak )( Ak1Ak2... Aj )
因此,
计算量=A[i:k]的计算量+A[k+1:j]的计算量+A[i:k] 和A[k+1:j]相乘的计算量 分析:⑴ 最优解的结构
计算A[i:j]的最优次序所包含的计算矩阵子链 A[i:k]和A[k+1:j]的次序也是最优的。
——最优子结构性质
⑵ 建立递归关系(动态规划函数)
设计算A[i:j],1≤i≤j≤n,所需要的最少数乘次数为 m[i,j],则原问题的最优值为m[1,n]。
当i=j时,A[i:j]=Ai。因此,m[i,i]=0,i=1,2,…,n
当i<j时,m[i, j] m[i, k ] m[k 1, j] pi1 pk p j 。
P(n)
n
1
P(k
1 )P(n
k
)
k1
n 1 P(n) (4n / n3/2 ) n 1
——P(n)随n的增长呈指数增长!
动态规划:
将矩阵连乘积 Ai Ai1... Aj 简记为A[i:j] ,这里i≤j,
考察计算A[i:j]的最优计算次序。 设这个计算次序在矩阵Ak和Ak+1之间将矩阵链断开,