矩阵乘法的动态规划解法

用动态规划法找出矩阵连乘积的最优计算次序。

1,  设矩阵连乘积AiAi+1…Aj简记为A[i:j],设最优计算次序在AkAk+1之间断开,则加括号方式为:

((AiAi+1…Ak)(Ak+1…Aj))

则依照这个次序,先计算A[i:k]A[K+1:j]然后再将计算结果相乘,计算量是:

A[i:k]的计算量加上A[K+1:j]的计算量再加上它们相乘的计算量。

问题的一个关键是:计算A[i:j]的最优次序所包含的两个子过程(计算A[i:k]A[K+1:j])也是最优次序。

2,  设计算A[i:j]所需的最少数乘次数为m[i][j]

i=j时为单一矩阵,则m[i][i]=0

i时,设最优计算次序在AkAk+1之间断开,则m[i][j]=m[i][k]+m[k+1][j]+pipk+1pj+1,其中p表示数组的维数,例如A0A56个数组(为了C语言的描述方便,下标从0开始),他们表示如下:

//p[0]:第一个矩阵的行数

    //p[1]:第一个矩阵的列数,第二个矩阵的行数

    //p[2]:第二个矩阵的列数,第三个矩阵的行数

k此时并未确定,需要从ij-1遍历以寻找一个最小的m[i][j]。我们把这个最小的k放在s[i][j]

 

以下是完整实现代码,以一个具体的例子实现,稍加修改即可通用。

#include 
using namespace std;
//////////////////////////////////////////////////////////////////////////////
//MatrixChain计算m[i][j]所需的最少数乘次数
//并记录断开位置s[i][j]
//////////////////////////////////////////////////////////////////////////////
void MatrixChain(int *p,int n,int **m,int **s)
{
     for(int i=0;i

打印结果是:

A1A2相乘

A0A1相乘

A3A4相乘

A3A5相乘

A0A3相乘

实际上要表达的是如下加括号方式:

((A0A1A2))((A3A4A5))

加了括号之后用第一个来代替,例如(A1A2 )可看作A1 ,这个结果的数乘次数是15125

你可能感兴趣的:(算法)