算法分析与设计实验二(关于动态规划问题)
2017-03-30 18:28
666 查看
第一个实验是求矩阵连乘问题
这个m和s是用6*6二维数组
--
(改)n*n变成n+1*n+1二维数组即此题7*7且if(i==0|| j==0) a[i][j]=0;
c语言版(同学需要,在java的基础上改成c= =)
矩阵连乘问题实际是从底向上进行计算。r的作用是让ij呈↘方向进行。r是由2到6(5次循环),此时的i是1到n-r+1即1-5,1-4,1-3,1-2,1-1;j是i+r-1,即2-6,3-6,4-6,5-6,6-6即第一个循环r=2实际是有m[1][2],m[2][3],m[3][4],m[4][5],m[5][6]。
r=3时是有m[1][3],m[2][4],m[3][5],m[4][6];
r=4时是有m[1][4],m[2][5],m[3][6];
r=5时是有m[1][5],m[2][6];
r=6时是有m[1][6];
然后
m[i][j] { ①0 ,i=j
②min{m[i][k]+m[k+1][j]+p[i-1]p[k]p[j]}(i<=k<j) , i<j
可以通过代码中定义的自变量为K的循环在i->j中实现比较取最小。
此题还可以通过备忘录的方法进行解答,算法大概思路是,先把m[i][j]循环遍历赋值0
然后写一个方法参数是i,j,比如方法叫做LookupChain(int i,int j)
把上面的m[x]][y]换成LookupChain(x,y);即可。
LookupChain(int i,int j){
if(m[i][j]>0) return m[i][j];
if(i==j)return 0;
int u=LookupChain(i,i)+LookupChain(i+1,j)+p[i-1]*p[i]*p[j];
...类似
}
实验2:最长公共子序列
实际上c[i][o] =0 c[0][j]=0;
然后i,j均到m,n遍历,m是X的长度,n是Y的长度。然后内部通过这种比较方式.
c[i][j]={① 0,i=0,j=0
②c[i-1][j-1]+1,i>0,j>0,x[i]=y[j]
③max{c[i][j-1],c[i-1][j] }i,j>0,x[i]!=y[j]
以书上的数据x={A,B,C,B,D,A,B};Y={B,D,C,A,B,A}为例得出最长公共子序列为BCBA
这个m和s是用6*6二维数组
package test1; import java.util.Scanner; import java.util.*; public class test1 { voidMatrixChain(int p[],int n,int m[][],int s[][])//m[6][6] s[6][6] p[7] n=5 { for(inti=0;i<n;i++)m[i][i]=0; for(intr=1;r<n;r++){ for(inti=0;i<n-r;i++){ intj=i+r; m[i][j]=m[i+1][j]+p[i]*p[i+1]*p[j+1]; s[i][j]=i+1; for(intk=i;k<j;k++){ intt=m[i][k]+m[k+1][j]+p[i]*p[k+1]*p[j+1]; if(t<m[i][j]){ m[i][j]=t; s[i][j]=k+1; } } } } } voidTraceback(int i,int j,int s[][]){ if(i==j)return; Traceback(i,s[i-1][j-1],s); Traceback(s[i-1][j-1]+1,j,s); System.out.printf("MultiplyA(%d,%d) and A(%d,%d)", i,s[i-1][j-1],s[i-1][j-1]+1,j); } publicstatic void main(String[] argn){ intp[]={30,35,15,5,10,20,25}; intn=6; intm[][]=new int ; ints[][]=new int ; test1a=new test1(); a.MatrixChain(p,n, m, s); for(inti=0;i<n;i++){ for(intj=0;j<n;j++) { System.out.printf("%6d",m[i][j]); } System.out.println(); } System.out.println("----------------------------------"); for(inti=0;i<n;i++){ for(intj=0;j<n;j++) { System.out.printf("%6d",s[i][j]); } System.out.println(); } a.Traceback(1,6,s); } }
--
(改)n*n变成n+1*n+1二维数组即此题7*7且if(i==0|| j==0) a[i][j]=0;
package test1; import java.util.Scanner; import java.util.*; public class test1 { voidMatrixChain(int p[],int n,int m[][],int s[][])//m[6][6] s[6][6] p[7] n=5 { for(inti=1;i<=n;i++)m[i][i]=0; for(intr=2;r<=n;r++){ for(inti=1;i<=n-r+1;i++){ intj=i+r-1; m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j]; s[i][j]=i; for(intk=i+1;k<j;k++){ intt=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j]; if(t<m[i][j]){ m[i][j]=t; s[i][j]=k; } } } } } voidTraceback(int i,int j,int s[][]){ if(i==j)return; Traceback(i,s[i][j],s); Traceback(s[i][j]+1,j,s); System.out.printf("MultiplyA%d,%d and A%d,%d", i,s[i][j],s[i][j]+1,j); } publicstatic void main(String[] argn){ intp[]={30,35,15,5,10,20,25}; intn=6; int m[][]=new int[n+1][n+1]; int s[][]=new int[n+1][n+1]; test1a=new test1(); a.MatrixChain(p,n, m, s); for(inti=1;i<=n;i++){ for(intj=1;j<=n;j++) { System.out.printf("%6d",m[i][j]); } System.out.println(); } System.out.println("----------------------------------"); for(inti=1;i<=n;i++){ for(intj=1;j<=n;j++) { System.out.printf("%6d",s[i][j]); } System.out.println(); } a.Traceback(1,6,s); } }
c语言版(同学需要,在java的基础上改成c= =)
#include<stdio aa62 .h> #include<stdlib.h> #include<string.h> void MatrixChain(int p[],int n,int **m,int **s)//m[6][6] s[6][6] p[7] n=5 { for(int i=1;i<=n;i++)m[i][i]=0; for(int r=2;r<=n;r++){ for(int i=1;i<=n-r+1;i++){ int j=i+r-1; m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j]; s[i][j]=i; for(int k=i+1;k<j;k++){ int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j]; if(t<m[i][j]){ m[i][j]=t; s[i][j]=k; } } } } } void Traceback(int i,int j,int **s){ if(i==j)return; Traceback(i,s[i][j],s); Traceback(s[i][j]+1,j,s); printf("Multiply A%d,%d and A%d,%d\n", i,s[i][j],s[i][j]+1,j); } int main(){ int p[]={30,35,15,5,10,20,25}; int n=6; // int m[][]=new int[n+1][n+1]; // int s[][]=new int[n+1][n+1]; int **m; int **s; m=(int **)malloc((n+1)*sizeof(int *)); s=(int **)malloc((n+1)*sizeof(int *)); for(int i=0;i<n+1;i++) { m[i]=(int *)malloc((n+1)*sizeof(int )); s[i]=(int *)malloc((n+1)*sizeof(int ));} for(int i=0;i<n+1;i++) for(int j=0;j<n+1;j++){ s[i][j]=0; m[i][j]=0; } MatrixChain(p, n, m, s); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++) { printf("%6d",m[i][j]); } printf("\n"); } printf("----------------------------------\n"); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++) { printf("%6d",s[i][j]); } printf("\n"); } Traceback(1,6,s); return 0; }
矩阵连乘问题实际是从底向上进行计算。r的作用是让ij呈↘方向进行。r是由2到6(5次循环),此时的i是1到n-r+1即1-5,1-4,1-3,1-2,1-1;j是i+r-1,即2-6,3-6,4-6,5-6,6-6即第一个循环r=2实际是有m[1][2],m[2][3],m[3][4],m[4][5],m[5][6]。
r=3时是有m[1][3],m[2][4],m[3][5],m[4][6];
r=4时是有m[1][4],m[2][5],m[3][6];
r=5时是有m[1][5],m[2][6];
r=6时是有m[1][6];
然后
m[i][j] { ①0 ,i=j
②min{m[i][k]+m[k+1][j]+p[i-1]p[k]p[j]}(i<=k<j) , i<j
可以通过代码中定义的自变量为K的循环在i->j中实现比较取最小。
此题还可以通过备忘录的方法进行解答,算法大概思路是,先把m[i][j]循环遍历赋值0
然后写一个方法参数是i,j,比如方法叫做LookupChain(int i,int j)
把上面的m[x]][y]换成LookupChain(x,y);即可。
LookupChain(int i,int j){
if(m[i][j]>0) return m[i][j];
if(i==j)return 0;
int u=LookupChain(i,i)+LookupChain(i+1,j)+p[i-1]*p[i]*p[j];
...类似
}
实验2:最长公共子序列
package test1; import java.util.Scanner; import java.util.*; public class test1 { /* c[i][j]{ 0 i=j=0; * c[i-1][j-1]+1 i,j>0;xi=yi; * max{c[i][j-1],c[i-1][j]} i,j>0;xi!=yi; * */ static void LCSLength(int m,int n,char x[],char y[],int c[][],int b[][]){//c b [m] int i,j; for(i=0;i<=m;i++)c[i][0]=0; for(i=0;i<=n;i++)c[0][i]=0; for(i=1;i<=m;i++){ for(j=1;j<=n;j++) { if(x[i-1]==y[j-1]){ c[i][j]=c[i-1][j-1]+1;b[i][j]=1; } else if(c[i][j-1]<=c[i-1][j]){ c[i][j]=c[i-1][j]; b[i][j]=2; } else{ c[i][j]=c[i][j-1]; b[i][j]=3; } } } } static void LCS(int i,int j,char x[],int b[][]){ if(i==0||j==0)return ; if(b[i][j]==1){ LCS(i-1,j-1,x,b); System.out.print(x[i-1]); } else if(b[i][j]==2)LCS(i-1,j,x,b); else if(b[i][j]==3)LCS(i,j-1,x,b); } public static void main(String[] argn){ char x[]={'A','B','C','B','D','A','B'}; char y[]={'B','D','C','A','B','A'}; int c[][]=new int[x.length+1][y.length+1]; int d[][]=new int[x.length+1][y.length+1]; LCSLength(x.length,y.length,x,y,c,d); System.out.print(" "); for(int j=0;j<y.length;j++) System.out.print(y[j]+" "); System.out.println(); for(int i=0;i<=x.length;i++){ if(i!=0) System.out.print(x[i-1]); else System.out.print(" "); for(int j=0;j<=y.length;j++) { System.out.printf("%3d",c[i][j]); } System.out.println(); } System.out.println("----------------------------------"); System.out.print(" "); for(int j=0;j<y.length;j++) System.out.print(y[j]+" "); System.out.println(); for(int i=0;i<=x.length;i++){ if(i!=0) System.out.print(x[i-1]); else System.out.print(" "); for(int j=0;j<=y.length;j++) { System.out.printf("%3d",d[i][j]); } System.out.println(); } LCS(x.length,y.length,x,d); } }
实际上c[i][o] =0 c[0][j]=0;
然后i,j均到m,n遍历,m是X的长度,n是Y的长度。然后内部通过这种比较方式.
c[i][j]={① 0,i=0,j=0
②c[i-1][j-1]+1,i>0,j>0,x[i]=y[j]
③max{c[i][j-1],c[i-1][j] }i,j>0,x[i]!=y[j]
以书上的数据x={A,B,C,B,D,A,B};Y={B,D,C,A,B,A}为例得出最长公共子序列为BCBA
相关文章推荐
- 算法分析与设计实验二(关于动态规划问题)
- 算法分析与设计实验三 回溯法 24点问题 n皇后问题
- n阶Hanoi塔问题 - 算法设计与分析实验1
- 【算法设计与分析】7、0/1背包问题,动态规划
- 计算机算法设计与分析之棋盘覆盖问题
- 贪心算法设计 关于区间选择问题
- OpenRisc-31-关于在设计具有DMA功能的ipcore时的虚实地址转换问题的分析与解决
- 统计数字问题[算法设计与分析]
- 归并排序和快速排序比较【算法设计与分析实验报告】
- 【算法设计-动态规划】钢条切割问题
- 【算法设计与分析】1、整数划分问题
- 算法设计与分析--N皇后问题实现程…
- [全程建模]关于分包的问题——用例、分析模型、设计模型的分包的作用和差异的对话
- 【算法分析与设计】最小生成树问题
- 分析邹健大哥的算法,终于问题解决了!!!(关于统计两日期间工作日)
- 算法设计与分析--矩阵连乘顺序问题…
- 归并排序和快速排序比较【算法设计与分析实验报告】
- 【算法设计与分析】2、棋盘覆盖问题
- 算法设计与分析--01背包问题(动态规划法解决)
- 【算法设计与分析】最大子段和问题