数学建模 动态规划Word下载.docx
- 文档编号:22214797
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:35
- 大小:46.74KB
数学建模 动态规划Word下载.docx
《数学建模 动态规划Word下载.docx》由会员分享,可在线阅读,更多相关《数学建模 动态规划Word下载.docx(35页珍藏版)》请在冰豆网上搜索。
若设x1=1,则在本次决策之后,可用的背包容量为r=116-100=16。
[x2,x3]=[0,1]符合容量限制的条件,所得值为15,但因为[x2,x3]=[1,0]同样符合容量条件且所得值为18,因此[x2,x3]=[0,1]并非最优策略。
即x=[1,0,1]可改进为x=[1,1,0]。
若设x1=0,则对于剩下的两种物品而言,容量限制条件为116。
总之,如果子问题的结果[x2,x3]不是剩余情况下的一个最优解,则[x1,x2,x3]也不会是总体的最优解。
例3-3[航费]某航线价格表为:
从亚特兰大到纽约或芝加哥,或从洛杉矶到亚特兰大的费用为$100;
从芝加哥到纽约票价$20;
而对于路经亚特兰大的旅客,从亚特兰大到芝加哥的费用仅为$20。
从洛杉矶到纽约的航线涉及到对中转机场的选择。
如果问题状态的形式为(起点,终点),那么在选择从洛杉矶到亚特兰大后,问题的状态变为(亚特兰大,纽约)。
从亚特兰大到纽约的最便宜航线是从亚特兰大直飞纽约,票价$100。
而使用直飞方式时,从洛杉矶到纽约的花费为$200。
不过,从洛杉矶到纽约的最便宜航线为洛杉矶-亚特兰大-芝加哥-纽约,其总花费为$140(在处理局部最优路径亚特兰大到纽约过程中选择了最低花费的路径:
亚特兰大-芝加哥-纽约)。
如果用三维数组(tag,起点,终点)表示问题状态,其中tag为0表示转飞,tag为1表示其他情形,那么在到达亚特兰大后,状态的三维数组将变为(0,亚特兰大,纽约),它对应的最优路径是经由芝加哥的那条路径。
当最优决策序列中包含最优决策子序列时,可建立动态规划递归方程(dynamic-programmingrecurrenceequation),它可以帮助我们高效地解决问题。
例3-4[0/1背包]在例3-2的0/1背包问题中,最优决策序列由最优决策子序列组成。
假设f(i,y)表示例15-2中剩余容量为y,剩余物品为i,i+1,.,n时的最优解的值,即:
和利用最优序列由最优子序列构成的结论,可得到f的递归式。
f(1,c)是初始时背包问题的最优解。
可使用(15-2)式通过递归或迭代来求解f(1,c)。
从f(n,*)开始迭式,f(n,*)由(15-1)式得出,然后由(15-2)式递归计算f(i,*)(i=n-1,n-2,.,2),最后由(15-2)式得出f(1,c)。
对于例15-2,若0≤y<10,则f(3,y)=0;
若y≥10,f(3,y)=15。
利用递归式(15-2),可得f(2,y)=0(0≤y<10);
f(2,y)=15(10≤y<14);
f(2,y)=18(14≤y<24)和f(2,y)=33(y≥24)。
因此最优解f(1,116)=max{f(2,116),f(2,116-w1)+p1}=max{f(2,116),f(2,16)+20}=max{33,38}=38。
现在计算xi值,步骤如下:
若f(1,c)=f(2,c),则x1=0,否则x1=1。
接下来需从剩余容量c-w1中寻求最优解,用f(2,c-w1)表示最优解。
依此类推,可得到所有的xi(i=1.n)值。
在该例中,可得出f(2,116)=33≠f(1,116),所以x1=1。
接着利用返回值38-p1=18计算x2及x3,此时r=116-w1=16,又由f(2,16)=18,得f(3,16)=14≠f(2,16),因此x2=1,此时r=16-w2=2,所以f(3,2)=0,即得x3=0。
动态规划方法采用最优原则(principleofoptimality)来建立用于计算最优解的递归式。
所谓最优原则即不管前面的策略如何,此后的决策必须是基于当前状态(由上一次决策产生)的最优决策。
由于对于有些问题的某些递归式来说并不一定能保证最优原则,因此在求解问题时有必要对它进行验证。
若不能保持最优原则,则不可应用动态规划方法。
在得到最优解的递归式之后,需要执行回溯(traceback)以构造最优解。
编写一个简单的递归程序来求解动态规划递归方程是一件很诱人的事。
然而,正如我们将在下文看到的,如果不努力地去避免重复计算,递归程序的复杂性将非常可观。
如果在递归程序设计中解决了重复计算问题时,复杂性将急剧下降。
动态规划递归方程也可用迭代方式来求解,这时很自然地避免了重复计算。
尽管迭代程序与避免重复计算的递归程序有相同的复杂性,但迭代程序不需要附加的递归栈空间,因此将比避免重复计算的递归程序更快。
3.2应用
3.2.10/1背包问题
1.递归策略
在例3-4中已建立了背包问题的动态规划递归方程,求解递归式(15-2)的一个很自然的方法便是使用程序15-1中的递归算法。
该模块假设p、w和n为输入,且p为整型,F(1,c)返回f(1,c)值。
程序15-1背包问题的递归函数
intF(inti,inty)
{//返回f(i,y).
if(i==n)return(y<
w[n])?
0:
p[n];
if(y<
w[i])returnF(i+1,y);
returnmax(F(i+1,y),F(i+1,y-w[i])+p[i]);
}
程序15-1的时间复杂性t(n)满足:
t
(1)=a;
t(n)≤2t(n-1)+b(n>1),其中a、b为常数。
通过求解可得t(n)=O(2n)。
例3-5设n=5,p=[6,3,5,4,6],w=[2,2,6,5,4]且c=10,求f(1,10)。
为了确定f(1,10),调用函数F(1,10)。
递归调用的关系如图15-1的树型结构所示。
每个节点用y值来标记。
对于第j层的节点有i=j,因此根节点表示F(1,10),而它有左孩子和右孩子,分别对应F(2,10)和F(2,8)。
总共执行了28次递归调用。
但我们注意到,其中可能含有重复前面工作的节点,如f(3,8)计算过两次,相同情况的还有f(4,8)、f(4,6)、f(4,2)、f(5,8)、f(5,6)、f(5,3)、f(5,2)和f(5,1)。
如果保留以前的计算结果,则可将节点数减至19,因为可以丢弃图中的阴影节点。
正如在例3-5中所看到的,程序15-1做了一些不必要的工作。
为了避免f(i,y)的重复计算,必须定义一个用于保留已被计算出的f(i,y)值的表格L,该表格的元素是三元组(i,y,f(i,y))。
在计算每一个f(i,y)之前,应检查表L中是否已包含一个三元组(i,y,*),其中*表示任意值。
如果已包含,则从该表中取出f(i,y)的值,否则,对f(i,y)进行计算并将计算所得的三元组(i,y,f(i,y))加入表L。
L既可以用散列(见7.4节)的形式存储,也可用二叉搜索树(见11章)的形式存储。
2.权为整数的迭代方法
当权为整数时,可设计一个相当简单的算法(见程序15-2)来求解f(1,c)。
该算法基于例3-4所给出的策略,因此每个f(i,y)只计算一次。
程序15-2用二维数组f[][]来保存各f的值。
而回溯函数Traceback用于确定由程序15-2所产生的xi值。
函数Knapsack的复杂性为(nc),而Traceback的复杂性为(n)。
程序15-2f和x的迭代计算
template<
classT>
voidKnapsack(Tp[],intw[],intc,intn,T**f)
{//对于所有i和y计算f[i][y]
//初始化f[n][]
for(inty=0;
y<
=yMax;
y++)
f[n][y]=0;
for(inty=w[n];
=c;
f[n][y]=p[n];
//计算剩下的f
for(inti=n-1;
i>
1;
i--){
f[i][y]=f[i+1][y];
for(inty=w[i];
f[i][y]=max(f[i+1][y],f[i+1][y-w[i]]+p[i]);
f[1][c]=f[2][c];
if(c>
=w[1])
f[1][c]=max(f[1][c],f[2][c-w[1]]+p[1]);
voidTraceback(T**f,intw[],intc,intn,intx[])
{//计算x
for(inti=1;
i<
n;
i++)
if(f[i][c]==f[i+1][c])x[i]=0;
else{x[i]=1;
c-=w[i];
x[n]=(f[n][c])?
1:
0;
3.元组方法(选读)
程序15-2有两个缺点:
1)要求权为整数;
2)当背包容量c很大时,程序15-2的速度慢于程序15-1。
一般情况下,若c>2n,程序15-2的复杂性为W(n2n)。
可利用元组的方法来克服上述两个缺点。
在元组方法中,对于每个i,f(i,y)都以数对(y,f(i,y))的形式按y的递增次序存储于表P(i)中。
同时,由于f(i,y)是y的非递减函数,因此P(i)中各数对(y,f(i,y))也是按f(i,y)的递增次序排列的。
例3-6条件同例3-5。
对f的计算如图15-2所示。
当i=5时,f由数对集合P(5)=[(0,0),(4,6)]表示。
而P(4)、P(3)和P
(2)分别为[(0,0),(4,6),(9,10)]、[(0,0)(4,6),(9,10),(10,11)]和[(0,0)(2,3)(4,6)(6,9)(9,10)(10,11)]。
为求f(1,10),利用式(15-2)得f(1,10)=max{f(2,10),f(2,8)+p1}。
由P
(2)得f(2,10)=11、f(2,8)=9(f(2,8)=9来自数对(6,9)),因此f(1,10)=max{11,15}=15。
现在来求xi的值,因为f(1,10)=f(2,6)+p1,所以x1=1;
由f(2,6)=f(3,6-w2)+p2=f(3,4)+p2,得x2=1;
由f(3,4)=f(4,4)=f(5,4)得x3=x4=0;
最后,因f(5,4)≠0得x5=1。
检查每个P(i)中的数对,可以发现每对(y,f(i,y))对应于变量xi,.,xn的0/1赋值的不同组合。
设(a,b)和(c,d)是对应于两组不同xi,.,xn的0/1赋值,若a≥c且b<d,则(a,b)受(b,c)支配。
被支配者不必加入P(i)中。
若在相同的数对中有两个或更多的赋值,则只有一个放入P(i)。
假设wn≤C,P(n)=[(0,0),(wn,pn)],P(n)中对应于xn的两个数对分别等于0和1。
对于每个i,P(i)可由P(i+1)得出。
首先,要计算数对的有序集合Q,使得当且仅当wi≤s≤c且(s-wi,t-pi)为P(i+1)中的一个数对时,(s,t)为Q中的一个数对。
现在Q中包含xi=1时的数对集,而P(i+1)对应于xi=0的数对集。
接下来,合并Q和P(i+1)并删除受支配者和重复值即可得到P(i)。
例3-7各数据同例15-6。
P(5)=[(0,0),(4,6)],因此Q=[(5,4),(9,10)]。
现在要将P(5)和Q合并得到P(4)。
因(5,4)受(4,6)支配,可删除(5,4),所以P(4)=[(0,0),(4,6),(9,10)]。
接着计算P(3),首先由P(4)得Q=[(6,5),(10,11)],然后又由合并方法得P(3)=[(0,0),(4,6),(9,10),(10,11)]。
最后计算P
(2):
由P(3)得Q=[(2,3),(6,9)],P(3)与Q合并得P
(2)=[(0,0),(2,3),(4,6),(6,9),(9,10).(10,11)]。
因为每个P(i)中的数对对应于xi,.,xn的不同0/1赋值,因此P(i)中的数对不会超过2n-i+1个。
计算P(i)时,计算Q需消耗(|P(i+1)|)的时间,合并P(i+1)和Q同样需要(|P(i+1)|)的时间。
计算所有P(i)时所需要的总时间为:
(nå
i=2|P(i+1)|=O(2n)。
当权为整数时,|P(i)|≤c+1,此时复杂性为O(min{nc,2n})。
如6.4.3节定义的,数字化图像是m×
m的像素阵列。
假定每个像素有一个0~255的灰度值。
因此存储一个像素至多需8位。
若每个像素存储都用最大位8位,则总的存储空间为8m2位。
为了减少存储空间,我们将采用变长模式(variablebitscheme),即不同像素用不同位数来存储。
像素值为0和1时只需1位存储空间;
值2、3各需2位;
值4,5,6和7各需3位;
以此类推,使用变长模式的步骤如下:
1)图像线性化根据图15-3a中的折线将m×
m维图像转换为1×
m2维矩阵。
2)分段将像素组分成若干个段,分段原则是:
每段中的像素位数相同。
每个段是相邻像素的集合且每段最多含256个像素,因此,若相同位数的像素超过256个的话,则用两个以上的段表示。
3)创建文件创建三个文件:
SegmentLength,BitsPerPixel和Pixels。
第一个文件包含在2)中所建的段的长度(减1),文件中各项均为8位长。
文件BitsPerPixel给出了各段中每个像素的存储位数(减1),文件中各项均为3位。
文件Pixels则是以变长格式存储的像素的二进制串。
4)压缩文件压缩在3)中所建立的文件,以减少空间需求。
上述压缩方法的效率(用所得压缩率表示)很大程度上取决于长段的出现频率。
例3-8考察图15-3b的4×
4图像。
按照蛇形的行主次序,灰度值依次为10,9,12,40,50,35,15,12,8,10,9,15,11,130,160和240。
各像素所需的位数分别为4,4,4,6,6,6,4,4,4,4,4,4,4,8,8和8,按等长的条件将像素分段,可以得到4个段[10,9,12]、[40,50,35]、[15,12,8,10,9,15,11]和[130,160,240]。
因此,文件SegmentLength为2,2,6,2;
文件BitsPerSegment的内容为3,5,3,7;
文件Pixels包含了按蛇形行主次序排列的16个灰度值,其中头三个各用4位存储,接下来三个各用6位,再接下来的七个各用4位,最后三个各用8位存储。
因此存储单元中前30位存储了前六个像素:
101010011100111000110010100011
这三个文件需要的存储空间分别为:
文件SegmentLength需32位;
BitsPerSegment需12位;
Pixels需82位,共需126位。
而如果每个像素都用8位存储,则存储空间需8×
16=128位,因而在本例图像中,节省了2位的空间。
假设在2)之后,产生了n个段。
段标题(segmentheader)用于存储段的长度以及该段中每个像素所占用的位数。
每个段标题需11位。
现假设li和bi分别表示第i段的段长和该段每个像素的长度,则存储第i段像素所需要的空间为li*bi。
在2)中所得的三个文件的总存储空间为11n+nå
i=1libi。
可通过将某些相邻段合并的方式来减少空间消耗。
如当段i和i+1被合并时,合并后的段长应为li+li+1。
此时每个像素的存储位数为max{bi,bi+1}位。
尽管这种技术增加了文件Pixels的空间消耗,但同时也减少了一个段标题的空间。
例3-9如果将例15-8中的第1段和第2段合并,合并后,文件SegmentLength变为5,6,2,BitsPerSegment变为5,3,7。
而文件Pixels的前36位存储的是合并后的第一段:
001010001001001100111000110010100011其余的像素(例15-8第3段)没有改变。
因为减少了1个段标题,文件SegmentLength和BitsPerPixel的空间消耗共减少了11位,而文件Pixels的空间增加6位,因此总共节约的空间为5位,空间总消耗为121位。
我们希望能设计一种算法,使得在产生n个段之后,能对相邻段进行合并,以便产生一个具有最小空间需求的新的段集合。
在合并相邻段之后,可利用诸如LZW法(见7.5节)和霍夫曼编码(见9.5.3节)等其他技术来进一步压缩这三个文件。
令sq为前q个段的最优合并所需要的空间。
定义s0=0。
考虑第i段(i>0),假如在最优合并C中,第i段与第i-1,i-2,.,i-r+1段相合并,而不包括第i-r段。
合并C所需要的空间消耗等于:
第1段到第i-r段所需空间+lsum(i-r+1,i)*bmax(i-r+1,i)+11
其中lsum(a,b)=bå
j=a
lj,bmax(a,b)=max{ba,...,bb}。
假如在C中第1段到第i-r段的合并不是最优合并,那么需要对合并进行修改,以使其具有更小的空间需求。
因此还必须对段1到段i-r进行最优合并,也即保证最优原则得以维持。
故C的空间消耗为:
si=si-r+lsum(i-r+1,i)*bmax(i-r+1,i)+11
r的值介于1到i之间,其中要求lsum不超过256(因为段长限制在256之内)。
尽管我们不知道如何选择r,但我们知道,由于C具有最小的空间需求,因此在所有选择中,r必须产生最小的空间需求。
假定kayi表示取得最小值时k的值,sn为n段的最优合并所需要的空间,因而一个最优合并可用kay的值构造出来。
例3-10假定在2)中得到五个段,它们的长度为[6,3,10,2,3],像素位数为[1,2,3,2,1],要用公式(15-3)计算sn,必须先求出sn-1,.,s0的值。
s0为0,现计算s1:
s1=s0+l1*b1+11=17kay1=1s2由下式得出:
s2=min{s1+l2b2,s0+(l1+l2)*max{b1,b2}}+11=min{17+6,0+9*2}+11=29
kay2=2
以此类推,可得s1.s5=[17,29,67,73,82],kay1.kay5=[1,2,2,3,4]。
因为s5=82,所以最优空间合并需82位的空间。
可由kay5导出本合并的方式,过程如下:
因为kay5=4,所以s5是由公式(15-3)在k=4时取得的,因而最优合并包括:
段1到段(5-4)=1的最优合并以及段2,3,4和5的合并。
最后仅剩下两个段:
段1以及段2到段5的合并段。
1.递归方
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数学建模 动态规划 数学 建模 动态 规划