目录
- 矩阵连乘
- 代码
- 代码说明
- 小结:
矩阵连乘
矩阵连乘问题是一个经典的动态规划问题,旨在通过确定矩阵的乘法顺序来最小化所需的乘法运算次数。在矩阵连乘中,我们有一系列矩阵 ( A_1, A_2, …, A_n ),其维度由一个数组 ( p ) 定义,其中 ( p[i-1] ) 是矩阵 ( A_i ) 的行数,而 ( p[i] ) 是矩阵 ( A_i ) 的列数。为了计算两个矩阵 ( A_i ) 和 ( A_j ) 的乘积,所需的标量乘法次数为 ( p[i-1] * p[k] * p[j] ),其中 ( k ) 是乘法操作的一个中间矩阵。
代码
在本博客中,我们将使用动态规划来解决这一问题,通过构建一个表来存储每个子问题的最优解。以下是实现这一算法的完整代码。
#include <iostream>
// N:矩阵个数
#define N 6
using namespace std;
// 递推求最优值
void MatrixChain(int *p, int n, int m[][N+1], int s[][N+1]){
/*
p:各矩阵大小
n:矩阵个数
m:最优值([i, j]相乘)
s:最优解
*/
for (int i=1; i<=n; i++) m[i][i] = 0; // 初始化自己乘以自己的次数为0
// r:相乘的矩阵的个数
for (int r=2; r<=n; r++){
// i:[i, i+r-1] 矩阵相乘
for (int i=1; i<=n-r+1; i++){
int j = i+r-1;
// 初始 m[i][j] 为 [i, i]*[i+1, i+r-1]
m[i][j] = m[i][i] + m[i+1][j] + p[i-1]*p[i]*p[j];
s[i][j] = i;
// 找出最小乘积次数 k = [i+1, j-1]
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[][N+1]){
// 终止条件
if (i == j) cout<<"A"<<i;
else{
cout<<"(";
TraceBack(i, s[i][j], s);
TraceBack(s[i][j]+1, j, s);
cout<<")";
}
}
int main() {
int p[N+1]={30,35,15,5,10,20,25};
int m[N+1][N+1],s[N+1][N+1];
MatrixChain(p, N, m, s);
TraceBack(1, N, s);
}
代码说明
在这段代码中,我们定义了两个主要的函数:MatrixChain 和 TraceBack。
MatrixChain 函数负责计算矩阵的最优乘法次数,并填充两个表 ( m ) 和 ( s )。其中,( m[i][j] ) 存储从矩阵 ( A_i ) 到 ( A_j ) 的最小乘法次数,( s[i][j] ) 则存储实现该最小乘法次数的分割点。
TraceBack 函数用于递归地输出最优的矩阵乘法顺序。在找到最优解后,通过回溯函数,可以有效地重构出矩阵相乘的顺序。
通过运行 main 函数,我们为矩阵链的维度提供了示例输入,并调用这两个函数,输出矩阵相乘的最优顺序。矩阵连乘不仅在计算机科学中有广泛应用,还在图像处理、科学计算等多个领域发挥着重要作用。
标签:连乘,int,代码,矩阵,算法,最优,乘法 From: https://blog.51cto.com/u_16672541/12100850