• (最大矩阵链乘)Matrix-chain product


    Matrix-chain product. The following are some instances.

    a)       <3, 5, 2, 1,10>

    b)       <2, 7, 3, 6, 10>

    c)       <10, 3, 15, 12, 7, 2>

    d)       <7, 2, 4, 15, 20, 5>

    矩阵链乘积:

    应用动态规划方法:

    • 1.刻画一个最优解的结构特征
    • 2.递归地定义最优解的值
    • 3.计算最优解的值,采用自底向上的方法
    • 4.利用计算出的信息构造一个最优解

    思想:

    1.最优括号化方案的结构特征

    用记号A[i..j]表示乘积A[i]A[i+1]..A[j]求值的结果,其中i <=j 。

    假设A[i]A[i+1]...A[j]的一个最优解括号把乘积在A[k]和A[k+1]之间分开,则对A[i]A[i+1]...A[j]最优解括号化方案中的“前缀”子链A[i]A[i+1]...A[k]的最优括号化的方法,必须是A[i]A[i+1]...A[k]的一个最有解括号化方案,类似的,A[k+1]A[k+2]…A[j]同理。

    2.设m[i][j]为计算矩阵A[i..j]所需的标量乘法运算次数的最小值;

    对整个问题,计算A[1..n]的最小代价就是m[1][n]。

    假设最优加全部括号将乘积A[i]A[i+1]...A[j]从A[k]和A[k+1]之间分开,i <= k < j。

    则:m[i][j] = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]

    关于对乘积A[i]A[i+1]...A[j]加全部括号的最小代价的递归定义为:

        m[i][j] = 0   if i == j

        m[i][j] = min(i<=k<j){m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]}  s[i][j]=k   if i < j

    用s[i][j]记录最优值m[i][j]的对应的分割点。

    3.用迭代自底向上的表格法来计算最优代价。

    4.利用保存在表格s[n][n]内的、经过计算的信息来构造一个最优解。

    按最优方式计算A[1..n]时,最终矩阵相乘次序是A[1..s[1][n]]A[a[1][n]+1..n]。

    之前的乘法可以递归地进行。

    public class Q1_Matrix_chain {
        public static int[] atest ={30,35,15,5,10,20,25};
        public static int[] a={3, 5, 2, 1, 10};
        public static int[] b={2, 7, 3, 6, 10};
        public static int[] c={10, 3, 15, 12, 7, 2};
        public static int[] d={7, 2, 4, 15, 20, 5};
        public static void main(String[] args)
        {
            System.out.println("<3, 5, 2, 1,10>");
            Matrix_Chain_Order(a);
            System.out.println("<2, 7, 3, 6, 10>");
            Matrix_Chain_Order(b);
            System.out.println("<10, 3, 15, 12, 7, 2>");
            Matrix_Chain_Order(c);
            System.out.println("<7, 2, 4, 15, 20, 5>");
            Matrix_Chain_Order(d);
    
        }
    
        public static void Matrix_Chain_Order(int[] a){
            int n = a.length-1;
            int[][] m = new int[n+1][n+1];
            int[][] s = new int[n+1][n+1];
            int i,j,k,t;
    
            for (i=0;i<=n;i++)
                m[i][i] = 0;
            for (i=0;i<=n;i++)
                s[i][i] = 0;
            for(t=2; t<=n; t++) //t is the chain length
            {
                for(i=1;i<=n-t+1;i++)//从第一矩阵开始计算,计算长度为t的最小代价
                {
                    j = i+t-1;//长度为t时候的最后一个元素
                    m[i][j] = 1000000;//初始化为最大代价
                    for(k=i;k<=j-1;k++)//寻找最优的k值,使得分成两部分k在i与j-1之间
                    {
                        int temp = m[i][k]+m[k+1][j] + a[i-1]*a[k]*a[j];
                        if(temp < m[i][j])
                        {
                        m[i][j] = temp;   //记录下当前的最小代价
                        s[i][j] = k;      //记录当前的括号位置,即矩阵的编号
                        }
                    }
                }
            }
            System.out.println("一个最优解为:");
            Display(s,1,n);
            System.out.println("
    计算的次数为:");
            System.out.println(m[1][n]);
        }
        public static void Display(int[][] s,int i,int j)
        {
            if( i == j)
            {
                System.out.print('A');
                System.out.print(i);
            }
            else
            {
                System.out.print('(');
                Display(s,i,s[i][j]);
                Display(s,s[i][j]+1,j);
                System.out.print(')');
            }
    
        }
    
    }
  • 相关阅读:
    Linux下修改Mysql的用户(root)的密码
    Mysql 用户权限管理
    mysql的四种启动方式
    MySQL慢日志的相关参数
    mysqlsla slow-query常用用法

    导包和模块注意的问题
    Python面向对象之魔法方法/双下方法
    __new__问题
    转:Python常见字符编码及其之间的转换
  • 原文地址:https://www.cnblogs.com/dear_diary/p/6929925.html
Copyright © 2020-2023  润新知