学好动态规划三步曲
Posted 大数据与计算智能
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学好动态规划三步曲相关的知识,希望对你有一定的参考价值。
动态规划,也是基于递归算法,但是其高明之处在于利用备忘录的方法来记录已经求解过的子问题的解,以避免对子问题的重复计算。而这些备忘录通常用一维数组或者二维数组来实现,以保存子问题的解。
下面介绍设计动态规划算法的三个步骤:
第一步:定义子问题。这个子问题通常由问题参数来决定,子问题解决了,则原问题也迎刃而解。而子问题的最优目标函数值,由数组来保存,通常问题参数有几个,数组就是几维的。
1. Fibonacci序列 考虑子问题Fibonacci序列F(i):求序列第i个数的值,涉及一个问题参数i,因此可以用一维数组F[i]来保存子问题F(i)的值。
2. 装配线调度问题 考虑子问题F1(j)(第1条装配线的第j个站点):汽车底盘从进厂点到装配点S1[j]的最短装配时间问题。涉及1个问题参数j,因此,可以用一维数组F1[j]来保存子问题F1(j)的最快完成时间。类似考虑子问题F2(j)。
3. 矩阵链乘积问题 考虑子问题m(i,j):如何对矩阵链Ai,Ai+1,...,Aj的乘积加括号,使得乘法次数最少。涉及两个问题参数i,j,因此,可以用二维数组m[i,j]来表示子问题m(i,j)的最小乘法次数。
4. 最长公共子序列 考虑子问题C(i,j):给定两个子序列Xi=<x1,x2,...,xi>和Yj=<y1,y2,...,yj>,寻找它们的最长公共子序列。涉及两个参数i,j,因此可以用二维数组C[i,j]来表示最长公共子序列的长度。
5. 0/1背包问题 令子问题V(i,w)表示求给定物品集合{1,2,...,i},背包载重量为的最大价值问题。涉及两个参数i,w,因此可以用二维数组V[i,w]来表示子问题V(i,w)的最大价值。
第二步:问题分解。原问题求解复杂,我们可以将原问题分解成若干个子问题,而且子问题与原问题相似,找出原问题与子问题之间的递归关系式。
1.Fibonacci序列 子问题F(i)分解为两个子子问题F(i-1)和F(i-2)。
2.装配线调度问题 子问题f1(j)(第1条装配线的第j个站点):如果j>1,到达点S1(j)有两种走法:
a) 从前一个装配点S1[j-1]直接传送到点S1[j]装配,涉及子子问题f1(j-1);
b) 从前一个装配点S2[j-1]装配后,传送到装配线1的装配点S1[j]装配,涉及子子问题f2(j-1)。
类似的考虑子问题f2(j)
3.矩阵链乘积问题 考虑子问题m(i,j),假设子问题m(i,j)最优加括号方式是把乘积在Ak和Ak+1之间分开:
AiAi+1...Aj=Ai...AkAk+1...Aj
子问题m(i,j)分成两个子子问题m(i,k)和m(k+1,j)
4.最长公共子序列 子问题C(i,j)的划分:
(1)如果xi=yj,则子问题划分为一个子子问题C(i-1,j-1);
(2)如果xi≠yj,则子问题C(i,j)划分为一个子子问题C(i,j-1)或者一个子子问题C(i-1,j);
5.0/1背包问题 子问题V(i,w)的划分有两种情况:
(1)如果wi>w,则子问题V(i,w)划分为子子问题V(i-1,w);
(2)如果wi≤w,则子问题V(i,w)分两种情况划分子问题:
a) 装进去,则子问题V(i,w)划分为一个子子问题V(i-1,w-wi);
b) 不装进去,则子问题V(i,w)划分为一个子子问题V(i-1,w);
第三步:最优子结构性质。导出子问题与子子问题目标值之间的关系式,1.Fibonacci序列 子问题F(i)分解为两个子子问题F(i-1)和F(i-2),递归关系是F(i)=F(i-1)+F(i-2),这里是自然的递归方程,没有最优化目标函数值。
2.装配线调度问题 假定到点S1[j]的最快装配路线
a) 如果是从前一个装配点S1[j-1]直接到点S1[j],则从进厂点到点S1[j-1]的装配路线p也一定是从进厂点到点S1[j-1]的最快装配路线。即有f1[j]=f1[j-1]+a1[j];
b) 如果是从前一个装配点S2[j-1]装配后,传送到装配线1的装配点S1[j]装配,则从进厂点到点S2[j-1]的装配路线p也一定是从进厂点到点S2[j-1]的最快装配路线。即有f1[j]=f2[j-1]+t2[j-1]+a1[j]。
要计算经过点S1[j]的最短时间f1[j],只需从上述两种情况中,选最优的即可:f1[j]=min{f1[j-1]+a1[j],f2[j-1]+t2[j-1]+a1[j]}
类似的,要计算过点S2[j]的最短装配时间f2[j],只需计算
f2[j]=min{f2[j-1]+a2[j],f1[j-1]+t1[j-1]+a2[j]}
3.矩阵乘积问题 假设m(i,j)的一种最优完全括号化方式是把乘积在Ak和Ak+1(i≤k<j)之间分开,则其中子问题m(i,k)和m(k+1,j)的加括号的方式也一定是最优的。即有m[i,j]=m[i,k]+m[k+1,j]+pi-1pkpj
事实上,我们不知道最优在哪里划分,划分的方式有j-i种,即k=i,i+1,...,j-1,因此,我们必须在j-i种划分中,选择使m[i,j]值最小的划分,因而可得递归方程:
4.最长公共子序列 子问题C(i,j)的划分:
(1)如果xi=yj,子问题划为为一个子子问题C(i-1,j-1),子问题C(i,j)的最优解里一定包含了子子问题C(i-1,j-1)的最优解,即一定有C[i,j]=C[i-1,j-1]+1;
(2)如果xi≠yj,假设子问题C(i,j)的最优划分为一个子子问题C(i,j-1),则一定有C[i,j]=C[i,j-1]
假设最优划分为一个子子问题C(i-1,j),即一定有C[i,j]=C[i-1,j]。事实上,我们不知道那种划分好,所以选两种划分里,最优的划分,即
C[i,j]=max{C[i,j-1],C[i-1,j]}。
5.0/1背包问题 子问题V(i,w)的划分有两种情况:
(1) 如果wi>w,则子问题V(i,w)的最优解里一定包括了子子问题V(i-1,w)的最优解,一定有V[i,w]=V[i-1,w-wi];
(2) 如果wi≤w,分两种情况情况进行讨论:
a) 如果子问题V(i,w)的最优解是装进去wi,则子问题V(i,w)的最优解包括了子子问题V(i-1,w-wi)的最优解,即有V[i,w]=V[i-1,w-wi]+vi;
b)如果不装进去,则子问题V(i,w)的最优解包括了子子问题V(i-1,w)的最优解;
事实上,我们不知道a) b)两种情况,那种方式更优,因此做最优的决策:
V[i-1,w-wi]=max{V[i-1,w-wi]+vi,V[i-1,w]}
以上是关于学好动态规划三步曲的主要内容,如果未能解决你的问题,请参考以下文章