zoukankan      html  css  js  c++  java
  • 矩阵链乘法问题

    问题描述:

    给定n个矩阵的链<A1,A1,A3...An>,矩阵Ai的规模(行列)为pi-1xpi(1<=i<=n),求矩阵链的完全括号化方案,使得矩阵乘积A1A2A3...An所需的标量乘法次数最小(假定所给举证链满足相容性,能够正确的进行矩阵运算)。

    注:假设矩M的规模为pxq,矩阵N的规模为qxr,那么,矩阵乘法MXN的标量乘法次数为pqr。

    分析:

    重点在于分析其最优子结构性质,并且导出递推公式。

    有j-i+1个矩阵,进行矩阵链乘:AiAi+1Ai+2..AkAk+1...Aj-1Aj,假设其最优括号化方案在Ak这个地方划分,则整个Ai到Aj矩阵链的最低代价三部分相加:

    1、前半部分分矩阵链AiAi+1Ai+2..Ak(其连乘后的结果是规模为pi-1xpk的矩阵)的最低代价;

    2、后半部分矩阵链Ak+1...Aj-1Aj(其连乘后的结果是规模为pkxpj的矩阵)最低代价;

    3、pi-1xpk阶的矩阵与pkxpj阶的矩阵相乘的标量乘法次数:pi-1pkpj。

    但是是Ak这个分割点是不定的,在Ai到Aj(出Aj外)之间的每矩阵都有可能作为这个最有的划分点。因此需要找出在遍历意义下的最小代价。

    假设C(i,j)是这些矩阵链乘的最小代价,那么递推式

    另外,对于输入数据的处理,因为矩阵链都是相容的,所以实际上可以用一个一维数组存储依次存储每个矩阵的行列数(要去重)。

    例如矩阵链A1...A6如下:

    可以用一维数组p来存储:

            int[] p = {30,35,15,5,10,20,25};

    A1的规模可以表示为:p[0]xp[1]

    A2的规模可以表示为:p[1]x[2]

    更一般的,Ai的规模可以表示为p[i-1]xp[i]

    算法实现:

    package agdp;
    public class Matrix {
        public static int getMinCost(int[] p){
            int n = p.length-1;//n为矩阵链中矩阵的个数,等于p长度-1
            int[][] aux = new int[n+1][n+1];//辅助数组,为方便计算,第0行和第0列不利用
            for (int l = 2; l <= n; l++) {//矩阵链的长度,从2开始,一直到长度为n结束,满足l=j-i+1
                for (int i = 1,j; i <= n-l+1; i++) {//当j=n是,i到最大值,所以i<=n-l+1
                    j = i+l-1;
                    aux[i][j] = Integer.MAX_VALUE;
                    for (int k = i; k < j; k++) {//遍历Ai到Aj矩阵链中每一个位置,并存储最小者
                        aux[i][j] = Math.min(aux[i][k]+aux[k+1][j]+p[i-1]*p[k]*p[j], aux[i][j]);
                    }
                }
            }
            return aux[1][n];
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int[] p = {30,35,15,5,10,20,25};
            int result = getMinCost(p);
            System.out.println(result);
        }
    }

    不同的l=j-i+1链的长度会导致l先链从做到右形成一个“滑动窗口”。

    其计算过程中全部的子问题的解都存储在aux数组中,该aux中有效数据是一个上三角矩阵。

  • 相关阅读:
    How To Build CyanogenMod Android for smartphone
    CentOS安装Code::Blocks
    How to Dual boot Multiple ROMs on Your Android SmartPhone (Upto Five Roms)?
    Audacious——Linux音乐播放器
    How to Dual Boot Multiple ROMs on Your Android Phone
    Everything You Need to Know About Rooting Your Android Phone
    How to Flash a ROM to Your Android Phone
    什么是NANDroid,如何加载NANDroid备份?
    Have you considered compiled a batman-adv.ko for android?
    BATMAN—Better Approach To Mobile Adhoc Networking (B.A.T.M.A.N.)
  • 原文地址:https://www.cnblogs.com/qcblog/p/7789132.html
Copyright © 2011-2022 走看看