第三章动态规划算法1PPT

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

i≤k<j
其中矩阵Ai ,1≤i≤n,的维数为pi–1×pi。 根据此递归式就可以直接用递归程序来实现。
算法设计与分析
5
直接递归的时间复杂性

根据前面的递归式不难得出的时间复杂性为 T(n) ≥ 1 + ∑(T(k) + T(n–k) + 1)
k=1 n–1 n–1
= 1 + (n – 1) +∑(T(k) + T(n–k))
算法设计与分析 2
不同计算顺序的数量
设n个矩阵的连乘积有P(n)个不同的计算顺序。 由此可得出关于 先在第k个和第k+1 P(n) 个矩阵之间将原矩阵序列 的递归式: 分成两个矩阵子序列, k=1,…, n;再分别 1 n= 1 n–1 P(n) = 对两个子序列完全加括号,最后对结果加括 ∑P(k) P(n–k) n>1 k=1 号,便得到原序列的一种完全加括号方式。 解此递归方程可得P(n) = C(n–1),其中 1 2n n/n3/2) C(n) = n+1 = Ω(4 n 所以P(n)随n的增长呈指数增长。因而穷举搜 索法不是有效的算法。
}}}
int t = m[i][k] + m[k+1][j] + p[i–1]*p[k]*p[j]; //对i<k<j, 逐个计算A[i, j] = A[i: k] A[k+1: j] if (t < m[i][j]) {m[i][j] = t; s[i][j] = k;} //记下较小的m[i][j]及相应的断点k
矩阵连乘问题
给定n个矩阵:A1, A2, …, An,其中Ai与Ai+1是 可乘的。确定一种连乘的顺序,使得矩阵连 乘的计算量为最小。 设A和B分别是p×q和q×r的两个矩阵,则乘 积C=AB为p×r的矩阵,计算量为pqr次数乘。 但是对于多于2个以上的矩阵连乘,连乘的顺 序却非常重要,因为不同的顺序的总计算量 将会有很大的差别。
1: 4
图中红框标出的 都是重复计算。
3: 4
1: 2 1: 1 2: 4 1:1 2: 3 2: 2 4: 4 3: 3 2: 2
3: 3
4: 4 1: 1 2: 2 2: 3 3: 3
1: 3
4: 4
2: 2 3: 3
3: 4 4: 4
1: 2 1: 1
3: 3 2: 2
7
算法设计与分析
消除重复的计算

算法设计与分析 12
动态规划的基本思想
将原问题分解为若干个子问题,先求子问题的 解,然后从这些子问题的解得到原问题的解。 这些子问题的解往往不是相互独立的。在求解 的过程中,许多子问题的解被反复地使用。为 了避免重复计算,动态规划算法采用了填表来 保存子问题解的方法。 在算法中用表格来保存已经求解的子问题的解, 无论它是否会被用到。当以后遇到该子问题时 即可查表取出其解,避免了重复计算。

算法设计与分析 4
建立递归关系
令m[i][j] , 1≤i, j≤n,为计算A[i, j] 的最少数乘 次数,则原问题为m[1][n]。 当i = j时,A[i, j]为单一矩阵, m[i][j] = 0; 当i<j时,利用最优子结构性质有: m[i][j] = min{m[i][k] + m[k+1][j] + pi–1pkpj}
1 1 2 3 4 5 6
0
2
0
3
2625 0
4
4375 6000 750 0
5
6
1 2 3 4 5 6
15750 7875
9375 11875 15125 7125 10500 2500 1000 5375 3500 6250
m[i][j]
0
5000
0
1 2 3 4 5 6
1
1
2
3 3 2 3
3
3 3 4
= n +∑T(k) + ∑T(n–k)
n –1 k=1 n –1 k=1 k=1 n–1
= n + 2∑T(k)
k=1

可用数学归纳法证明T(n)≥2n–1 = Ω(2n)。 直接递归算法的时间复杂性随n的指数增长。
算法设计与分析 6
直接递归中有大量重复计算

直接递归中有大量重复计算,如A[1: 4]计算中:
算法设计与分析
10
MatrixChain的运行举例
MatrixChain 用矩阵 m[i][j], s[i][j] 存放子问题 A[i: j] 当 r=2 ,执行第 (5) 句完成了相邻矩阵 –1]*p[i]*p[j] 设要计算矩阵连乘积 A4A[i][i+1]=p[i A MatrixChain 当 r=3 i=1 时,执行第 (5) 句计算 A[1:1][2:3] A[2:2][3:4] , m[1][3] = 当 r=3 , i=3 时,执行第 (5) 句计算 A[3:3][4:5] , m[3][5] = 1A2A 3 5A 6,其维数分别 执行 for (int i 将如下面红色箭头所示的过程逐个计算 = 1; i <= n; i++) m[i][i] = 0后将对角线元素全 类似的,当 r=4 、 5 、 6时,可以计算出相应的 m[i][j] 及其相 由 m[1][6]=15125 可知这 6A 个矩阵连乘积的最小运算次数为 当 r=3, ,i=2 i=4 时,执行第 (5) 句计算 A[4:4][5:6] ,m[2][4] m[4][6] = 的计算,并在 s[i][j] 中添入了相应的断点。其中的第 (7) 句因 的最小计算量以及相应的断点。 m[2][3] m[3][4] + p[0]*p[1]*p[3] p[1]*p[2]*p[4] = 2625 750 +35*15*10 +30*35*5 = 7875 6000 m[4][5] + p[2]*p[3]*p[5] = 1000 +15*5*20 = 2500 为 35 × 35, 35 × 15, 15 × 5, 5 × 10, 10 × 20, 20 × 25, 子问题 A[i: j] : 部置零,即子问题 A[i][i] = 0 。 应的断点 s[i][j] ,如下图中所示: 15125 。由 s[1][6] = 3 可知 A[1: 6] 的最优计算次序为 A[1: 3] m[5][6] + p[3]*p[4]*p[6] = 5000 +5*10*25 = 6250 为 jp =6] i+1(k=i+1) 而被跳过去了,实际并没有执行。 执行第 (7) 句计算 A[2:3][4:4] , tt = 即 =35, p =35, p可知 p p =20, pA[1: =25 。 A[4: ;由 s[1][3]=1 A[1: 3] 的最优计算次序为 1] 执行第 (7) 句计算 A[3:4][5:5] , = m[3][4]+m[5][5]+ A[4:5][6:6] m[4][5]+m[6][6]+ 0 (7)句计算 1 2=15, 3=5, 4=10, p 6+ 执行第 A[1:2][3:3] , t = m[2][3]+m[4][4]+ m[1][2] +5m[3][3] p[1]*p[3]*p[4] = 2625+0+35*5*10 = 4375 < 6000 ,所以 A[2: 3];由s[4][6]=5 可知A[4: 6]的最优计算次序为 A[4: 5] p[2]*p[4]*p[5] =15750+0+35*15*5 750+0+15*10*20 = 3750 > 2500 ,所以 p[3]*p[5]*p[6] 1000+0+5*20*25 3500 < 6250 p[0]*p[2]*p[3] = = 18375 > 7875 ,所以 m[2][4] 改为 A[6: 6];因此最优计算次序为: m[3][5] 仍为 2500 ,断点仍为 3 。 (A1(A2A3))((A4A5)A6)。 m[4][6] 改为4375 3500,断点改为 ,断点改为 5。 m[1][3] 不变,断点仍为 1。 3

算法设计与分析 13
动态规划的基本要素

最优子结构:问题的最优解是由其子问题的最 优解所构成的。 最优子结构性质使我们能够以自底向上的方式 递归地从子结构的最优解构造出问题的最优解。 重叠子问题:子问题之间并非相互独立的,而 是彼此有重叠的。 因为子问题重叠,所以存在着重复计算。这样 就可以用填表保存子问题解的方法来提高效率。
算法设计与分析 14

动态规划的基本方法





动态规划通常可以按以下几个步骤进行: (1)找出最优解的性质,并刻画其结构特征; (2)递归地定义最优值; (3)以自底向上的方式计算出各子结构的最优值 并添入表格中保存; (4)根据计算最优值时得到的信息,构造最优解。 步骤1~3是动态规划算法的基本步骤。若需要 最优解,则必须执行第4步,为此还需要在第3 步中记录构造最优解所必需的信息。
m[2][4] m[1][2] m[2][3] m[3][4]
m[i][i+1] = pi–1pipi+1
m[i][i] = 0
9
m[1][1] m[2][2] m[3][3] m[4][4]
算法设计与分析
源自文库
消除重复的矩阵连乘算法

Void MatrixChain(int p, int n, int **m, int **s) { for (int i = 1; i <= n; i++) m[i][i] = 0; //将对角线元素赋值为零,即单个矩阵计算量为0 for (int r = 2; r <= n; r++) for (int i = 1; i <= n – r +1; i++) { int j = i + r – 1; (5) m[i][j] = m[i+1][j] + p[i–1]*p[i]*p[j]; //计算A[i, j] = A[i: i] A[i+1: j] 能。此处分开是为 第(5)步与第(7)步 s[i][j] = i; //记下断点i 了给 m[i][j]赋初值。 能否合在一起 ? (7) for (int k = i + 1; k < j; k++) {
3 3
s[i][j]
3 5 4
5
算法设计与分析
11
MatrixChain的时间复杂性
算法MatrixChain的主要计算取决于程序 中对r、i和k的三重循环。循环体内的计 算量为O(1),1≤ r、i、k≤n,三重循环的 总次数为O(n3)。因此该算法时间复杂性 的上界为O(n3),比直接递归算法要有效 得多。算法使用空间显然为O(n2)。 这种算法称为动态规划。

算法设计与分析
1
不同计算顺序的差别

设矩阵A1, A2和A3分别为10×100, 100×5和 5×50的矩阵,现要计算A1A2A3 。 若按((A1A2)A3)来计算,则需要的数乘次数为 10×100×5 + 10×5×50 = 7500 若按(A1(A2 A3))来计算,则需要的数乘次数为 100 ×5 ×50+ 10×100×50 = 75000 后一种计算顺序的计算量竟是前者的10倍! 所以,求多个矩阵的连乘积时,计算的结合 顺序是十分重要的。

算法设计与分析 8
自底向上的计算

例如对于A1A2A3A4,依据递归式以自底向上的 方式计算出各个子问题,其过程如下:
其中 m[1][3] = 例如: m[1][1]+m[2][3]+p0p1p3 m[i][j] = mini≤k<j min m[1][3] m[2][4] m[1][2]+m[3][3]+p p2p3 {m[i][k]+m[k+1][j]+pi0–1p kp j }

算法设计与分析 3
分解最优解的结构
将矩阵连乘积AiAi+1…Aj记为A[i: j]。 若A[1: n] 的一个最优解是在矩阵Ak和Ak+1处 断开的,即A[1: n] = (A[1: k] A[k+1: n]),则 A[1: k]和A[k+1: n]也分别是最优解。 事实上,若A[1: k]的一个计算次序所需计算量 更少的话,则用此计算次序替换原来的次序, 则得到A[1: n]一个更少的计算量,这是一个矛 盾。同理A[k+1: n]也是最优解。 最优子结构性质:最优解的子结构也最优的。
要消除重复计算,可在在计算过程中保存已解 决的子问题的答案。这样,每个子问题只计算 一次,而在后面需要时只要简单查一下,从而 避免重复计算。 计算方式可依据递归式自底向上地进行。 注意到在此问题中,不同的有序对 (i, j)就对应 不同的子问题,因此不同的子问题个数个数最 多只有Cn2+ n = (n2)个。 这样便可以得到多项式时间的算法。
相关文档
最新文档