问题分析
矩阵连乘问题是经典的动态规划问题,其主要是n个矩阵进行矩阵乘法运算时,通过括号改变运算的先后顺序,减少运算次数,找到最佳划分方法,求解最少运算次数。
算法分析
矩阵连乘问题中动态规划可以帮助我们找到从每个矩阵到另一个矩阵的最小运算次数以及对应的划分,我们用dp[i][j]存储从矩阵A[i]到矩阵A[j]的运算次数。每当对从矩阵A[i]连乘到矩阵A[j]求解最小连乘括号划分时,我们引入A[i]到A[j]连乘序列中的一个矩阵A[k]。我们从第i+1个矩阵开始尝试,直到矩阵A[j],如果有更优解——得到更小的dp[i][j],那么就更新,并且将第k个矩阵视为一个分割界限进行记录,直到完成对dp[1][n]的更新。
①初始化
因为每个矩阵对自身不用进行运算,所以我们将dp[i][j]的对角线元素初始化为0
for(int i=1;i<matrixNum;i++){
//初始化对角线元素为零
dp[i][i]=0;
}
②核心算法
1)引入变量length用来记录当前矩阵连乘的数目,我们从两个矩阵连乘开始寻找最优解,直到求出n个矩阵连乘的最优解。
2)引入变量j记录连乘矩阵的最后一个矩阵的下标。
3)引入二维数组decison[i][j]记录每轮矩阵A[i]连乘到矩阵A[j]的分割界限,每一轮都会不断更新,直到找到本轮最好的分割界限。
4)核心算法共三轮循环:
第一轮用来控制由小问题不断向大问题扩展——先求解两两矩阵相乘最优解,再进行连续三个矩阵相乘求最优解,最终求出n个矩阵连乘的最优解。
第二轮连乘起点矩阵遍历的控制。每轮循环需要先把分割界限设定在起点矩阵,对dp[i][j]进行初始化。
第三轮连乘矩阵A[i]到矩阵A[j]之间,中间矩阵A[k]的遍历控制。
注意 :个人认为最难理解的地方在于,每次对dp[i][j]的更新都要将分割界限k两侧并且运算后的整体矩阵单独拿出来进行相乘运算并且加和—— matrixIndex[i-1]*matrixIndex[i]*matrixIndex[j];。
int j=0;
for(int length=2;length<=matrixNum;++length){
//length表示矩阵连乘的矩阵数目
for (int i=1;i<=matrixNum-length+1;++i){
j=i+length-1;//length-1表示本次矩阵连乘的结果加和次数,j记录连乘矩阵的最后一个矩阵的下标
dp[i][j] = dp[i+1][j]+matrixIndex[i-1]*matrixIndex[i]*matrixIndex[j];//先将分割界限定在i,即最后计算第一个矩阵与后面整体相乘
decision[i][j] = i;//记录分割界限
for (int k = i + 1; k < j; ++k){
int tmp = dp[i][k]

本文详细解析了使用动态规划解决矩阵连乘问题的方法,通过初始化对角线元素、核心算法的三轮循环及结果展示,阐述如何找到最佳的矩阵连乘顺序以达到最小的运算次数。动态规划在这里起到了关键作用,帮助优化计算过程。
2万+

被折叠的 条评论
为什么被折叠?



