动态规划求解矩阵连乘
目录
1.两个矩阵相乘
对于两个矩阵乘法:A(row1,col1)*B(row2,col2)=C(row3,col3)
有以下性质:
1.row3 = row1
2.col3 = col1
3.col1 = row2
4.乘法次数 = row1*col1*col2。(C中的元素(i,j)是由A中的第i行与B中的第j列中的元素对应乘而来,而C中又有row1*col2个这样的元素)。
2. 三个矩阵相乘
再来考虑下三个矩阵相乘A1A2A3。
可以是(A1A2)A3也可以是A1(A2A3)。
而两种算式虽然结果是一样的,但是过程中需要计算的乘法次数是不一样的。
如以下例子:
3个矩阵{A1, A2, A3}连乘,设3个矩阵的维数分别为10×100, 100×5, 5×50。
若按((A1A2)A3)计算,需要数乘次数为:10×100×5+10×5×50=7500;
若按(A1(A2A3))计算,需要数乘次数为:100×5×50+10×100×50=75000。
因此是可以通过乘的次序不同来简化运算的,所以才有了此篇。
3.n个矩阵相乘与动态规划递推公式
显然对上一个例子,我们在第二个矩阵之后断开,先分别算A1A2相乘的结果再将这结果与A3相乘的计算次数最少。
那么假设我们要算n个矩阵相乘也是一样的,需要选择在第i个矩阵后断开。然后对比在每个节点断开时的运算次序,选择最少的就是最优解。
由此动态规划的递推公式就出来了:
其中pi表示第i个矩阵的列,也即第i+1个矩阵的行。
图中的m数组即动态规划的dp数组。
从递推公式中可以看出算m[i,j]需要事先知道m[i,k]还有m[k+1,j],而无论是m[i,k]还是m[k+1,j]的长度都比m[i,j]短,所以计算整个m数组的顺序应该是从矩阵链长度短的推到长度长的,最后得到结果m[1][n]。
4.伪代码
for i<-1 to n do
dp[i][i] = 0
for length<-2 to n do //length是相乘矩阵链的长度
for begin<-1 to n-length+1 do //begin是相乘矩阵链的第一个矩阵
end = begin + length - 1 //end是相乘矩阵链的最后一个矩阵
dp[begin][end]<-∞
for index <- begin to end-1 do
temp = dp[begin][index] + dp[index+1][end] + p[begin-1]*p[index]*p[end]
if temp < dp[begin][end] then
dp[begin][end] = temp
5.伪代码实现
public class MatrixMul {
public static void main(String[] args) {
int num = 6;
int p[] = {30, 35, 15, 5, 10, 20, 25};
int result = mul(num,p);
System.out.println(result);
}
private static int mul(int num, int[] p) {
int dp[][] = new int[num+1][num+1];
for (int i = 1; i < dp.length; i++) {
dp[i][i] = 0;
}
for (int length = 2; length < dp.length; length++) {
for (int begin = 1; begin <= dp.length-length; begin++) {
int end = begin + length -1;
dp[begin][end] = Integer.MAX_VALUE;
for (int index = begin; index < end; index++) {
int temp = dp[begin][index] + dp[index+1][end] + p[begin-1]*p[index]*p[end];
if(temp < dp[begin][end]) {
dp[begin][end] = temp;
}
}
}
}
return dp[1][num];
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构