矩阵连乘问题详解
2016-10-12 17:56
169 查看
关于矩阵连乘问题这两天上网搜了很多资料,以下三篇博客帮我弄明白了动态规划中的矩阵连乘问题,
首先非常感谢三位博主,下面是三篇博客的地址,加上自己的一点补充。
crystal_yi的博客:http://blog.sina.com.cn/s/blog_64018c250100s123.html###
陈斌彬的技术博客:http://www.tuicool.com/articles/JfUjyib
上面两位博主对此问题做了详细的讲解
下面这位博主对此算法做了完整的实现
Jason Damon:http://www.cnblogs.com/Jason-Damon
以下的代码自己增加了一点点补充
void MatrixChain(int *p,int n,int **m,int **s)
{ //m是最优值,s是最优值的断开点的索引,n为题目所给的矩阵的个数(下面例子中)
//矩阵段长度为1,则m[][]中对角线的值为0,表示只有一个矩阵,没有相乘的.
for(int i = 1;i<=n;i++) m[i][i] = 0; //初始化单个矩阵连乘的最小次数,本题中n=6
for(int r = 2;r<=n;r++){//r表示矩阵的长度(2,3…逐渐变长)
for(int i = 1;i<=n-r+1;i++){
//从第i个矩阵Ai开始,长度为r,则矩阵段为(Ai~Aj)
int j = i+r-1;//当前矩阵段(Ai~Aj)的起始为Ai,尾为Aj
//求(Ai~Aj)中最小的,其实k应该从i开始,但先记录第一个值,k从i+1开始,这样也可以。
//例如对(A2~A4),则i=2,j=4,下面一行先得出m[2][4]=m[3][4]+p[1]*p[2]*p[4],即A2(A3A4)
m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];
s[i][j] = i;//记录断开点的索引
<span style="white-space:pre"> </span>//以下for循环求出(Ai~Aj)中的最小数乘次数
for(int k = i+1 ; k<j;k++){
//例如对(A2~A4),则k=2,此处for循环计算(A2A3)A4 此次for循环不在包含
//A2(A3A4)因为上面已经得出m[2][4]=m[3][4]+p[1]*p[2]*p[4],即A2(A3A4)
//将矩阵段(Ai~Aj)分成左右2部分(左m[i][k],右m[k+1][j]), 不包含A2(A3A4)再加上左右2部分最后相乘的次数(p[i-1] *p[k]*p[j])
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; //保存最小的断开位置,即最优的结果
}//if
}//k
}//i
}//r
}//MatrixChain
首先非常感谢三位博主,下面是三篇博客的地址,加上自己的一点补充。
crystal_yi的博客:http://blog.sina.com.cn/s/blog_64018c250100s123.html###
陈斌彬的技术博客:http://www.tuicool.com/articles/JfUjyib
上面两位博主对此问题做了详细的讲解
下面这位博主对此算法做了完整的实现
Jason Damon:http://www.cnblogs.com/Jason-Damon
以下的代码自己增加了一点点补充
void MatrixChain(int *p,int n,int **m,int **s)
{ //m是最优值,s是最优值的断开点的索引,n为题目所给的矩阵的个数(下面例子中)
//矩阵段长度为1,则m[][]中对角线的值为0,表示只有一个矩阵,没有相乘的.
for(int i = 1;i<=n;i++) m[i][i] = 0; //初始化单个矩阵连乘的最小次数,本题中n=6
for(int r = 2;r<=n;r++){//r表示矩阵的长度(2,3…逐渐变长)
for(int i = 1;i<=n-r+1;i++){
//从第i个矩阵Ai开始,长度为r,则矩阵段为(Ai~Aj)
int j = i+r-1;//当前矩阵段(Ai~Aj)的起始为Ai,尾为Aj
//求(Ai~Aj)中最小的,其实k应该从i开始,但先记录第一个值,k从i+1开始,这样也可以。
//例如对(A2~A4),则i=2,j=4,下面一行先得出m[2][4]=m[3][4]+p[1]*p[2]*p[4],即A2(A3A4)
m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];
s[i][j] = i;//记录断开点的索引
<span style="white-space:pre"> </span>//以下for循环求出(Ai~Aj)中的最小数乘次数
for(int k = i+1 ; k<j;k++){
//例如对(A2~A4),则k=2,此处for循环计算(A2A3)A4 此次for循环不在包含
//A2(A3A4)因为上面已经得出m[2][4]=m[3][4]+p[1]*p[2]*p[4],即A2(A3A4)
//将矩阵段(Ai~Aj)分成左右2部分(左m[i][k],右m[k+1][j]), 不包含A2(A3A4)再加上左右2部分最后相乘的次数(p[i-1] *p[k]*p[j])
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; //保存最小的断开位置,即最优的结果
}//if
}//k
}//i
}//r
}//MatrixChain
相关文章推荐
- Java中文问题详解
- LILO启动问题详解
- Fedora core 4 常见问题及解决详解(100个)
- linux操作系统中关机问题详解
- java/jsp中 中文问题详解
- SQL SERVER 安装问题详解
- Java中文问题详解,底层编码解剖
- 经典海盗问题详解
- Java中文问题详解
- Java中文问题详解(高手必读)
- 无法关机问题的详解
- Fedora core 4 常见问题及解决详解(100个)
- Java处理中文话问题详解
- java中 中文问题详解
- Java中文问题详解
- Java中文问题详解,底层编码解剖
- java-Java中文问题详解,底层编码解剖
- Java中文问题详解
- 堆栈问题详解
- java/jsp中 中文问题详解