1 / 17

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

算法设计与分析 第三章 动态规划. 杨圣洪. 3.7 图像压缩. 将 像素点 灰度值序列 {p 1 ,p 2 ,…,p n } 分割成 m 个连续段 S 1 , S 2 ,… , S m 。 其中 0≤p i ≤255 。 0< 段内点数 <=255 Si 的点数记为 L[i] ,因 L[i]  255 , L[i] 的 2 进制之位数  8 Si 中各点的 p i 之 2 进制使用 相同位数 ( 即最大位数 bmax[i]) 。 p i 最大值 ≤ 255, 故 bmax[i] =ceil(log 2 (max( pi) ))  8 3 位 表示

Download Presentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 算法设计与分析第三章 动态规划 杨圣洪

  2. 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位

  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,1kmin(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)) jki ,从点j到点i像素值最大者的位数,多算几个s[i]体会计算式 • i前255点内最少存贮空间,以i为结束点的段最多为255个点或最多包括之前的所有点。 • 算法复杂度分析:由于bmax(s,i)中对k的循环次数不超256,故对每一个确定的i,可在时间O(1)内完成的计算。因此整个算法所需的计算时间为O(n)。段长不超常量是技巧!

  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,1kmin(i,255) • 这个公式是对的,如下公式是错的! • s[i]=min{s[i-k]-11+k*bmax(i-k+1, i)}+11,1kmin(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 故这三个结果是对的

  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,1kmin(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

  6. s[i]=min{s[i-k]+k*bmax(i-k+1, i)}+11 bmax(i,j)=ceil(log2(max{p[k]}+1)) 1kmin(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; }

  7. s[i]=min{s[i-k]+k*bmax(i-k+1, i)}+11 kmax(i,j)=ceil(log2(max{p[k]}+1)) 1kmin(i,255) 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; }} l[n]最后一段长度,分隔点为n 倒数第1分隔点t2=n-l[n], 倒数第2分隔点t3=t2-l[t2] ……

  8. 3.7 图像压缩

  9. 递归计算最优值与构造最优解 • 递归计算最优值算法描述:P70-71 • 构造最优解算法描述:P71-72 • Compress:S(n)=O(n),T(n)=O(n)

  10. 3.8 电路布线 • 如下图所示,上方的点仅与下方一点相连 • 点i的对应点记为(i),其连线记为(i, (i)),称为第i条连线 • 制板时将线分布到若干绝缘层上,同层上的连线不许相交,为节约成本要使层次减少,每层不相交的连线增多 • 为此要求出某个电路不相交连线的最大值?,即求 • 导线集Nets={(i, (i)),1in}的最大不相交子集。 • 相交判断:任何1i<jn, 起点小终点大则相交 (i, (i))和(j, (j))相交 (i)>(j)。 各点的对象 ∏={8,7,4,2,5,1,9,3,10,6} 此图板书

  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)

  12. N(i,j)={(t, (t))|(t, (t))∈Nets, t≤i, (t)≤j} 起点≤i,终点≤j. 最优子结构性质 (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<iMNS(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)

  13. 递归计算最优值 • 8 板书 ∏={8,7,4,2,5,1,9,3,10,6} 行i的终点 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)=1 size[4,1]=size[3,1], size[4,2]=max(size[3,2],size[3,1]+1)=1 size[5,1]=size[5,2]=size[5,3]=size[5,4]=上行值 size[5,5]=max(size[4,5],size[4,4]+1) ……

  14. 递归计算最优值 板书 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); }

  15. 递归计算最优值 板书 ∏={8,7,4,2,5,1,9,3,10,6} 当size[i,j]<>size[i-1,j]才加边 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=8j=C[9]-1=9 size[8][9]=size[7][9] j不变 i=9j=10 size[i][j]<>size[i-1][j] net[0]=(9,C[9]) i=n=10j=n=10 size[i][j]=size[i-1][j] j不变

  16. 跟踪路径 (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]. 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++ } }

  17. 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);} 递归计算最优值 • 算法复杂性: • MNS算法:T(n)=O(n2),S(n)=(n2) • Traceback算法:T(n)=O(n) 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++ ;}}

More Related