• 矩阵链相乘


    问题:n个矩阵M1M2……Mn链乘法的耗费,取决于n-1个乘法执行的顺序。现在要找到其最小次数的乘法执行顺序。

    如,n = 4,有以下可能的顺序:

    (M1(M2(M3M4)))

    (M1((M2M3)M4))

    ((M1M2)(M3M4))

    (((M1M2)M3)M4)

    ((M1(M2M3))M4)

    如果使用暴力算法枚举,时间复杂度为O(2n)。运用动态规划技术,可以将时间复杂度降为O(n3).

    算法基本思路:

    1.得到最小乘法次数

    (1)将矩阵序列在其中找出某个k位置,将其分为两部分;

    分别求出这两部分的最优解,然后再将其加上这两部分相乘的耗费,就是用当前划分所需要的乘法次数;

    依次枚举按k划分,比较并取最小乘法次数。

    (2)从上面的思路可以知道构造最优解的方法,但如果自顶向下必然会导致很多重复运算(类比斐波拉契数列),因此采用自底向下的打表方法,逐步求出最优解。

    2.构造矩阵乘法序列

    在上面算法的基础上,每次获取最优解的时候都标记当前k的位置;然后将序列从最终结果处逐步按 k 回溯,并划分(即添加括号)。

    算法具体实现:

    输入:r[0...n],     r[0...n-1]表示M0M1……Mn-1的行数,r[n]表示Mn的列数。因为相邻矩阵的行列相等,所以此数组即可包含所有数据。

    1.最小乘法次数

    构造最优表:c[0...n-1][0...n-1],    c[i][j]表示 MiMi+1……M的乘法次数

    枚举k(i < k <= j),C[i][j] = min( c[i][k-1] + c[k][j] + r[i]*r[k]*r[j+1] )

    其中:

        c[i][k-1]表示 MiMi+1……Mk-1 的乘法次数

        c[k][j]表示 MkMk+1……M的乘法次数

        r[i] = M的行数

        r[k] = M的行数

        r[j+1] = M的列数

    再利用 t[i][j] 保存当前最优的k,不难看出,k 就是那个序列的划分。

    最终结果 c[0][n-1] = min( c[0][k-1] + c[k][n-1] + r[0]*r[k]*r[n] ),其中 0 < k <= n

    2.构造最优解

    设 i = 0, j = n-1 即c[i][j] 为最小乘法次数

    要输出当前的序列,利用t[i][j]划分序列,输出它们的序列即可;一直划分到仅剩下一个元素即 i = j.(递归)

    实现代码:

    /*
    input:r[0..n];            //r[0..n-1] = the number of rows of M0...Mn-1, r[n] = the number of columns of Mn-1
    because the number of columns of Mi is equal to the number of rows of Mi+1, so enough information
    
    table:c[0..n-1][0..n-1]        //c[i][j] = the number of multiplications of (Mi * Mi+1 *...* Mj)
        
    enumerate k, i< k <=j, c[i][j] = min(c[i][k-1] + c[k][j] + r[i]*r[k]*r[j+1])
    because Mi * Mi+1 *...* Mj = (Mi * Mi+1 *...* Mk-1)*(Mk * Mk+1 *...* Mj)
            c[i][k-1] = the number of multiplications of (Mi * Mi+1 *...* Mk-1)
            c[k][j] = the number of multiplications of (Mk * Mk+1 *...* Mj)
            r[i] = the number of rows of Mi
            r[k] = the number of rows of Mk
            r[j+1] = the number of columns of Mj
    */
    
    public class MatrixChain {
        
        public static String getMinMatrixChain(int[] r){
            //return minimum number of multiplications
            int[][] c = new int[r.length-1][r.length-1];
            int[][] t = new int[r.length-1][r.length-1];
            //init diagonal0
            for(int i = 0; i < c.length; i ++){
                c[i][i] = 0;
                t[i][i] = -1;
            }
            //computer diagonal1..n-1
            for(int d = 1; d < c.length; d ++){
                for(int i = 0; i < c.length-d; i ++){
                    int j = i + d;
                    //compute c[i][j]
                    c[i][j] = Integer.MAX_VALUE;
                    for(int k = i+1; k <= j; k ++){
                        int temp = c[i][k-1] + c[k][j] + r[i]*r[k]*r[j+1];
                        if(temp < c[i][j]){
                            c[i][j] = temp;
                            t[i][j] = k;
                        }
                    }
                }
            }
    //        for(int i = 0; i < c.length; i ++){
    //            for(int j = 0; j < c.length; j ++){
    //                System.out.print(c[i][j] + "	");
    //            }
    //            System.out.println();
    //        }
            return c[0][c.length-1] + "/" + getSequence(t, 0, c.length-1);
        }
    
        private static String getSequence(int[][] t, int i, int j){
            //return the matrix sequence of mul
            if(i == j)                //atom
                return "M" + i;
            //t[i][j] = the place of "("
            return "(" + getSequence(t, i, t[i][j]-1) + getSequence(t, t[i][j], j) + ")";
        }
    
        public static void main(String[] args) {
            int[] r = {4, 5, 3, 6, 4, 5};
            String[] result = getMinMatrixChain(r).split("/");
            System.out.println(result[0] + ": " + result[1]);
        }
    
    }
    Java
  • 相关阅读:
    lhgdialogv3.13 使用点滴
    CheckBoxList 取值 及选中相关用法
    repeater 及 gridview 中绑定短日期
    数据库中日期大小的判断
    父子不同窗口间刷新传值
    子级Repeater获取父级Repeater绑定项的值
    vs.net 2010 web 项目中使用 webservice
    web打印实现方案 Lodop6.034 使用方法总结
    用 showModalDialog 方法回传数据到父页中去
    vs.net2010中使用 Ajax Control Toolkit
  • 原文地址:https://www.cnblogs.com/7hat/p/3428225.html
Copyright © 2020-2023  润新知