算法设计与分析 第三章 动态规划

17
算算算算算算算 算算算 算算算算 算算算

Upload: hannelore-evan

Post on 02-Jan-2016

91 views

Category:

Documents


8 download

DESCRIPTION

算法设计与分析 第三章 动态规划. 杨圣洪. 3.7 图像压缩. 将 像素点 灰度值序列 {p 1 ,p 2 ,…,p n } 分割成 m 个连续段 S 1 , S 2 ,… , S m 。 其中 0≤p i ≤255 。 0< 段内点数

TRANSCRIPT

Page 1: 算法设计与分析 第三章  动态规划

算法设计与分析

第三章 动态规划

杨圣洪

Page 2: 算法设计与分析 第三章  动态规划

22

3.7 图像压缩 将像素点灰度值序列 {p1,p2,…,pn} 分割成 m 个连续段 S1, S2 ,…

, Sm 。 其中 0≤pi≤255。 0< 段内点数 <=255 Si 的点数记为 L[i] ,因 L[i]255, L[i]的 2 进制之位数 8 Si 中各点的 pi之 2 进制使用相同位数 ( 即最大位数 bmax[i]) 。 pi 最大值≤ 255,故 bmax[i]=ceil(log2(max(pi)))8 3 位表示 如图像大块区域是浅色则像素值 pi <32, bmax[i] 5段 i 所占存贮空间 L[i]*bmax[i]+ 点数 (8位 )+ 各点长度 (3位 ) 为解压需要,要保存点数 L[i] 、各点像素值的位数 b[i] ,共有 3+8=11 位。故 Si 的存贮空间为: L[i]*b[i]+11

总长 (L[1]*bmax[1]+11)+…+(L[m]*bmax[m]+11)= (L[i]*bmax[i]+11m, i=1~m 图象压缩问题:确定 S1,S2,…,Sm ,使得存储空间最少。 每段 b[i]与 L[i] 如何组合。每段有表示点数与点长 11 位

Page 3: 算法设计与分析 第三章  动态规划

最优子结构性质 设 (L[1],bmax[1]),… , (L[m],b[m])是 {p1,p2,…,pn} 的最优分

段。 L[i]段 i 的长度, bmax[i] 是段 i 的各像素值表示位数 如果整体最优能导出局部最优,否则矛盾 ( 画示意图,局部换

成最优后整体值会缩小 , 这与整体最优矛盾 ) 。 为了找出最优分段,依次将每个点作为分段点 (!!!) ,分别计

算其区间长度与存贮空间,然后找出最佳分隔点。 设 s[i] 是以 p[i] 分段点时,该段的存储位空间值则 s[i]=min{s[i-k]+k*bmax(i-k+1, i)}+11 , 1kmin(i,255) s[i-1]+1*bmax(i-1+1,i)+11, s[i-2]+2*bmax(i-2+1,i)+11, bmax(j,i)=ceil(log2(max{p[k]}+1)) jki , 从点 j 到点 i 像素值

最大者的位数,多算几个 s[i] 体会计算式 i前 255 点内最少存贮空间,以 i 为结束点的段最多为 255 个

点或最多包括之前的所有点。 算法复杂度分析:由于 bmax(s,i) 中对 k 的循环次数不超 256 ,

故对每一个确定的 i ,可在时间 O(1) 内完成的计算。因此整个算法所需的计算时间为 O(n) 。段长不超常量是技巧!

Page 4: 算法设计与分析 第三章  动态规划

最优子结构性质 设 (L[1],bmax[1]),… , (L[m],b[m])是 {p1,p2,…,pn} 的最优分段。

L[i]段 i 的长度, bmax[i] 是段 i 的各像素值表示位数 如果整体最优能导出局部最优,否则矛盾 ( 画示意图,局部换成

最优后整体值会缩小 , 这与整体最优矛盾 ) 。 设 s[i] 是以 p[i] 分段点时,该段的存储位空间值则 s[i]=min{s[i-k]+k*bmax(i-k+1, i)}+11 , 1kmin(i,255) 这个公式是对的,如下公式是错的! s[i]=min{s[i-k]-11+k*bmax(i-k+1, i)}+11 , 1kmin(i,255) S[0]=0 S[1]=s[0]+1*bmax(1,1)+11=0+8+11=19 呆算 8+11 S[2]=s[1]+1*bmax(2,2)=27 ,S[0]+2*bmax(1,2)=0+16=16 min(27,16)+11=27 呆算 2*8+11= S[3]=S[2]+1*bmax(3,3)=27+8=35,S[1]+2*bmax(2,3)=11+16=27 S[0]+3*bmax(1,3)=0+24=24, min(35,27,24)+11=35 呆算: 3*8+11=35 故这三个结果是对的

Page 5: 算法设计与分析 第三章  动态规划

最优子结构性质 设 (L[1],bmax[1]),… , (L[m],b[m])是 {p1,p2,…,pn} 的最优分段。

L[i]段 i 的长度, bmax[i] 是段 i 的各像素值表示位数 如果整体最优能导出局部最优,否则矛盾 ( 画示意图,局部换

成最优后整体值会缩小 , 这与整体最优矛盾 ) 。 设 s[i] 是以 p[i] 分段点时,该段的存储位空间值则 s[i]=min{s[i-k]+k*bmax(i-k+1, i)}+11 , 1kmin(i,255) S[0]=0 S[1]=s[0]+1*bmax(1,1)+11=0+8+11=19 呆算 8+11 S[2]=s[1]+1*bmax(2,2)=27 ,S[0]+2*bmax(1,2)=0+16=16 min(27,16)+11=27 呆算 2*8+11= S[3]=S[2]+1*bmax(3,3)=27+8=35,S[1]+2*bmax(2,3)=11+16=27 S[0]+3*bmax(1,3)=0+24=24, min(35,27,24)+11=35 S[4]=S[4-1]+1*bmax(4,4)=35+7=42,S[4-2]+2*bmax(3,4)=27+16=43 S[4-3]+3*bmax(2,3)=19+24=43, S[4-4]+4*bmax(1,4)=32 min(42,43,32)+11=43

Page 6: 算法设计与分析 第三章  动态规划

1kmin(i,255)void compress(int n,int p[],int s[],int l[],int b[],int bmax[]){// 点数 , 像素值 , 结点 i 为终点段存贮空间 , 段长 , 本段内的素存贮位int Lmax=255,header=11; //L[i] 的值占 8 位, b[i] 值占 3 位s[0]=0;// 没有一个点也要点数与最大位数,因此数组 n+1 位for (int i=1;i<=n;i++){

b[i]=length(p(i)); //p(i) 存贮位数 int bmax0=b[i]; // 最大存贮位数初值为 p(i) 的位数

s[i]=s[i-1]+bmax0; //以 i 为终点的段长度初值 k=1 段时该段的长度l[i]=1;bmax[i]=bmax0; //以 i 为终点的段内结点数初值为 1

for (int k=2;k<=i && k<=Lmax;k++){if (bmax0<b[i-k+1]) bmax0=b[i-k+1];// 前面各点像素值位数已知if (s[i]>s[i-k]+k*bmax){s[i]=s[i-k]

+k*bmax0;l[i]=k;bmax[i]=bmax0;}}

s[i]+=header;// 添加固定的长度值 }} //L[i] 保存着此点 i 前多少位共一段

int length(int i){ int k=1;i=(i>>1); //i=i/2; while (i>0){k++; i=(i>>1);} return k;}

s[i]=min{s[i-k]+k*bmax(i-k+1, i)}+11bmax(i,j)=ceil(log2(max{p[k]}+1))

Page 7: 算法设计与分析 第三章  动态规划

1kmin(i,255)s[i]=s[i]=minmin{s[i-k]+k*bmax(i-k+1, i)}+11{s[i-k]+k*bmax(i-k+1, i)}+11kmax(i,j)=ceil(log2(kmax(i,j)=ceil(log2(maxmax{p[k]}+1)){p[k]}+1))

l[n] 最后一段长度,分隔点为 n倒数第 1 分隔点 t2=n-l[n],倒数第 2 分隔点 t3=t2-l[t2]……

int Tb(int n,int sp[],int l[]){ int i=n; // 最后一段结束位置 m=1; while (i>=1){

sp[m]=i;//段 i 的结束位置如 500 m++; // 逆向记录其位置 i=i-l[i]; } // 前段结束位置如 500-11 return m-1;}// 返回段数void Output(int l[],int b[],int n){int sp[]=new int[n+1]; int m=Tb(n,sp,l); // 计算各段结束点for (int j=m;j>=1;j--){cout<<l[sp[j]]<<' '<<bmax[sp[j]]<<' '<<s[sp[j]]<<endl; }}

Page 8: 算法设计与分析 第三章  动态规划

3.7 图像压缩

Page 9: 算法设计与分析 第三章  动态规划

递归计算最优值与构造最优解递归计算最优值算法描述: P70-71

构造最优解算法描述: P71-72

Compress: S(n)=O(n), T(n)=O(n)

Page 10: 算法设计与分析 第三章  动态规划

3.8 电路布线 如下图所示,上方的点仅与下方一点相连点 i 的对应点记为 (i) ,其连线记为 (i, (i)), 称为第 i 条

连线 制板时将线分布到若干绝缘层上,同层上的连线不许相

交,为节约成本要使层次减少,每层不相交的连线增多 为此要求出某个电路不相交连线的最大值?,即求 导线集 Nets={(i, (i)),1in} 的最大不相交子集。 相交判断:任何 1i<<jn , 起点小终点大则相

交 (i, (i))和 (j, (j)) 相交 (i)>>(j) 。∏={ 8, 7, 4, 2, 5, 1, 9, 3, 10,

6 }

此图板书

各点的对象

Page 11: 算法设计与分析 第三章  动态规划

最优子结构性质 记 N(i,j)={(t, (t))|(t, (t)) Nets,t≤i, ∈ (t)≤j} 起点≤ i, 终点≤ j. N(1,1)= { 起≤ 1, 终≤ 1} ={}=N(1,2)…=N(1,7)=MNS(1,1) N(1,8)= { 起≤ 1, 终≤ 8} ={(1,8)} N(2,1)= { 起≤ 2, 终≤ 1} ={}=N(2,2)=N(2,3)…=N(2,6) N(2,7)={ 起≤ 2, 终≤ 7}={(2,7)} N(2,8)={ 起≤ 2, 终≤ 8}={(1,8),(2,7)} 相交 N(3,9)={ 起≤ 3, 终≤ 9}={(1,8),(2,7),(3,4)} 相交 N(7,9)={ 起≤ 7, 终≤ 9}={(1,8),(2,7),(3,4),(4,2),(5,5),(6,1),(7,8)} 不相交 ={(3,4),(5,5),(7,8)} ,是最大吗? next N(i,j) 的最大不相交子集记为 MNS(i,j), Size(i,j)=|MNS(i,j)| 。 (1)当 i=1 时, (2)当 i>1 时, 板 N(i,j),MNS(i,j),Size(i,j),MNS(1,j),MNS(i>1,j)

)1())}1(,1{(

)1(),1(),1(

j

jjNjMNS

Page 12: 算法设计与分析 第三章  动态规划

1212

最优子结构性质(2)当 i>1 时, a) 终点 j<(i)即 i 的端点在 j 的右边 (i, (i))N(i,j) N(i,j) 与前点 i-1 相同即

N(i,j)=N(i-1,j) MNS(i,j)=MNS(i-1,j) Size(i,j)=Size(i-1,j) 。 b) 终点 j≥(i)(i 终点 (i)在 j 的左边 )(i, (i))N(i,j) ) 分成以下二种情况:

① (i, (i))MNS(i,j) 即新边在最大不相交子集中: 对于 MNS(i,j) 中不为 (i, (i))的 (t, (t)) ,其起点 t<i, 其端点 (t)<(i)(i是 N(i,j) 各边起点最大值故 t<i. 假设 (t)>(i)则 (i, (i))与 (t, (t)) 相交故矛

盾 ) MNS(i,j)-{(i, (i))}=N(i-1, (i)-1) 最大不相交子集 MNS(i-1, (i)-1) Size(i,j)-1=Size(i-1,j-1) ( 假设 MNS(i,j)-{(i, (i))}MNS(i-1, (i)-1) MNS(i,j)MNS(i-1, (i)-1){(i, (i))}, 而MNS(i-1, (i)-1){(i, (i))} 是不

相交子集 ,故MNS(i,j) 不是最大,矛盾,故假设错。 ) ② (i, (i))MNS(i,j) 即新边不在最大不相交子集中:

(t, (t))MNS(i,j) ,其起点 t<iMNS(i,j)N(i-1,j) MNS(i,j)MNS(i-1,j) Size(i,j)≤Size(i-1,j) 。

又MNS(i-1,j)MNS(i,j)Size(i-1,j)Size(i,j)Size(i,j)=Size(i-1,j) 。电路布线问题整体最优 Size(i,j) 导出局部最优 Size(i-1,j-1)

N(i,j)={(t, N(i,j)={(t, (t))|(t, (t))|(t, (t)) Nets,∈(t)) Nets,∈t≤i, t≤i, (t)≤j} (t)≤j} 起点≤起点≤ i,i, 终点≤终点≤ j.j.

Page 13: 算法设计与分析 第三章  动态规划

1313

递归计算最优值 8

)(}1)1)(,1(),,1(max{

)(),1(),(

1)2)1(1

)1(0),1(

1)1

ijiiSizejiSize

ijjiSizejiSize

ij

jjSize

i

时,当

时,当 板书

∏={ 8, 7, 4, 2, 5, 1, 9, 3, 10,6 } Size[1,1]=…=size[1,7]=0,size[1,8]=size[1,9]=1

size[2,1]=size[1,1],…,size[2,6]=size[1,6]size[2,7]=max(size[1,7],size[1,6]+1)=1,…size[3,1]=size[2,1],…size[3,3]=size[2,3]size[3,4]=max(size[2,4],size[2,3]+1)=1size[4,1]=size[3,1],size[4,2]=max(size[3,2],size[3,1]+1)=1size[5,1]=size[5,2]=size[5,3]=size[5,4]= 上行值size[5,5]=max(size[4,5],size[4,4]+1)……

行 i 的终点

Page 14: 算法设计与分析 第三章  动态规划

递归计算最优值

)(}1)1)(,1(),,1(max{

)(),1(),(

1)2)1(1

)1(0),1(

1)1

ijiiSizejiSize

ijjiSizejiSize

ij

jjSize

i

时,当

时,当

void MNS(int C[], int n, int **size) // 数组元素 n+1{ // 每个 i 的连接边 (i) 用数组 C 表示 ,如 {8,7,4,2,5,1,9,3,10,6} ,size 要返回 ! for (int j=1; j<C[1]; j++) size[1][j]=0;//i=1,j<(1) 即结点 1 的终点 for (int j=C[1]; j<=n; j++) size[1][j]=1; //i=1,j>=(1) 即结点 1 的终点 for (int i=2; i<=n; i++) // 起点 i从 2 起 { for (int j=1; j<C[i]; j++) size[i][j]=size[i-1][j]; //j< (i) for (int j=C[i]; j<=n; j++) //j>= (i) size[i][j]=max(size[i-1][j], size[i-1][C[i]-1]+1); }//起 i终 i 范围为最后点 n,j>= (n) size[n][n]==max(size[n-1][n], size[n-1][C[n]-1]+1);}

板书

Page 15: 算法设计与分析 第三章  动态规划

1515

递归计算最优值

)(}1)1)(,1(),,1(max{

)(),1(),(

1)2)1(1

)1(0),1(

1)1

ijiiSizejiSize

ijjiSizejiSize

ij

jjSize

i

时,当

时,当 板书

∏={ 8, 7, 4, 2, 5, 1, 9, 3, 10, 6 }i=2 j=C[3]-1=3 size[2][3]=size[1][3]

i=3 j=4 size[3][4]<>size[2][4] net[3]=(3,C[3])

i=4 j=C[5]-1=4 size[4][4]=size[3][4] 不变i=5 j=8 size[5][8]<>size[4][8] net[2]=(5,C[5])

i=6 j=C[7]-1=8 size[6][8]=size[5][8] j 不变 i=7 j=9 size[7][9]<>size[6][9] net[1]=(7,C[7])

i=8 j=C[9]-1=9 size[8][9]=size[7][9] j 不变i=9 j=10 size[i][j]<>size[i-1][j]

net[0]=(9,C[9])

i=n=10 j=n=10 size[i][j]=size[i-1][j] j 不变

当 size[i,j]<>size[i-1,j] 才加边

Page 16: 算法设计与分析 第三章  动态规划

跟踪路径

void Traceback(int C[],int **size, int n, int **Net, int &m){ int j=n; m=0; for (int i=n; i>1; i--) { if (size[i][j]!=size[i-1][j]){ Net[m][0]=i; Net[m][1]=C[i]; m++; j=C[i]-1; } } if (j>=C[1]) { Net[m][0]=1; Net[m][1]=C[i]; m++ }}

(i, (i))MNS(i,j) 时 Size(i,j)=Size(i-1,j-1)+1 若 size[i][j]=size[i-1][j-1]+1即 size[i][j]!=size[i-1][j] 就往MNS 中加边 (i, (i)). 保存该边起始号 i, 终止号 (i)即 C[i].

Page 17: 算法设计与分析 第三章  动态规划

递归计算最优值

算法复杂性: MNS 算法: T(n)=O(n2), S(n)=(n2) Traceback 算法: T(n)=O(n)

void MNS(int C[], int n, int **size) // 数组元素 n+1{ // 每个 i 的连接边 (i) 用数组 C 表示 ,如 {8,7,4,2,5,1,9,3,10,6} ,size 要返回 ! for (int j=1; j<C[1]; j++) size[1][j]=0;//i=1,j<(1) for (int j=C[1]; j<=n; j++) size[1][j]=1; //i=1,j>=(1) for (int i=2; i<n; i++) // 起点 i从 2 起 { for (int j=1; j<C[i]; j++) size[i][j]=size[i-1][j]; for (int j=C[i]; j<=n; j++) //j>= (i) size[i][j]=max(size[i-1][j], size[i-1][C[i]-1]+1); }//起 i终 i 范围为最后点 n,j>= (n) size[n][n]==max(size[n-1][n], size[n-1][C[n]-1]+1);}void Traceback(int C[],int **size, int n, int **Net, int &m){ int j=C[n]; m=0; for (int i=n; i>1; i--) { if (size[i][j]!=size[i-1][j]){ Net[m][0]=i; Net[m][1]=C[i]; m++; j=C[i]-1; } } if (j>=C[1]) { Net[m][0]=1; Net[m][1]=C[i]; m++ ;}}