[动态规划]矩阵连乘问题

题目:

        给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少?

       下面给出矩阵连乘的模板:

void MetrixChain(int p[],int n){
    for(int i = 1;i <= n;i++){
        m[i][i] = 0;  //矩阵链长度为0
    }

    for(int r = 2;r <= n;r++){  //r控制矩阵链长度
        for(int i = 1;i <= n-r+1;i++){  //i控制起点 j控制终点
            int j = i+r-1;

            // k = i的情形,为m[i][j]设置初始值,以便和res比较
            m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];
            s[i][j] = i;

            for(int k = i+1;k < j;k++){   // i < k < j 的情形
                int res = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
                if(res < m[i][j]){
                    m[i][j] = res;
                    s[i][j] = k;
                }
            }
        }
    }
}

        先给大家举一个例子,方便理解。

        假设题目给出了6个矩阵以及每个矩阵的行数和列数,如下图所示:

         我们可以根据这6个矩阵的行数和列数的规律,设定一个数组 p 来存放。

         接下来我们画一个二维表格,行表示起点,列表示终点。每个方格表示从A[i]到A[j]的最少数乘次数 m[i][j]。例如 m[1][3]表示(A1A2A3)的最小数乘次数。注意:只有 i < j 的时候才有最小数乘次数。

       我们按照矩阵链长度递增的方式依次计算 m[i][j]。

        当矩阵链长度为1时,根据矩阵的性质可知,单个矩阵无法相乘,所以 (A1) = 0 ,(A2) = 0,以此类推。在表格中补全单个矩阵的最小数乘次数,如下图所示。

        当矩阵链长度为2时,我们依次计算m[1][2],m[2][3],m[3][4],......,m[i][i+1](i <= n-2+1,理由见代码)。在代码里面矩阵链长度为2的不考虑 k 划分。因为 k 要满足 i <= k < j 条件,而此时 j = i + 1,所以 k 只能等于 i 。此时将 k = i 代入通用公式m[i][j]  = m[i][k] + m[k+1][j] + p[i-1]×p[i]×p[j] 得到 m[i][j]  = m[i][i] + m[i+1][j] + p[i-1]×p[i]×p[j] ,进一步化简可得m[i][j]  = m[i+1][j] + p[i-1]×p[i]×p[j]。例如m[1][2] = ((A1)A2) = m[1][1] + m[2][2] + p[0]×p[1]×p[2] = 0 + 0 + p[0]×p[1]×p[2] = 30×35×15 = 15750。断开位置 k 为 i,故s[i][j] = i。

        这里解释一下为什么代码里要先算出所有矩阵链长度为2的数乘次数。因为计算矩阵链长度为3的数乘次数其实就是在矩阵链长度为2的基础上,再和另一个矩阵相乘,以此类推。我们先把矩阵链长度小的全部算出来并存在二维数组里,这样在计算矩阵链长度大的数乘次数时就可以直接用,不用重复计算了。

         当矩阵链长度为3时,我们依次计算m[1][3],m[2][4],......,m[i][i+2](i <= n-3+1,理由见代码)。例如m[2][4] = A2A3A4 ,这里的 k 就可以通过for循环来控制,用通用公式计算m[i][j]  = m[i][k] + m[k+1][j] + p[i-1]×p[i]×p[j]。当 k = i+1时,m[2][4] = (A2A3)A4 = m[2][3] + m[4][4] + p[1]×p[3]×p[4] = 2625 + 0 + 35×5×10 = 4375  。算出来之后还需要和原来的值进行比较大小,看是否需要更新 m[i][j],s[i][j]。

         当矩阵链长度为4时,最少数乘次数如下。

        当矩阵链长度为5时,最少数乘次数如下。

        当矩阵链长度为6时,最少数乘次数如下。 

        大家可以观察一下计算最少数乘次数 m[i][j] 的顺序,很有特色。按照矩阵链长度递增的方式依次计算 m[i][j]。 

        在此过程中,我们同时可以将每一次断开位置 k 记为 s[i][j]。

        希望大家学有所获!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值