zoukankan      html  css  js  c++  java
  • 矩阵连乘之动态规划

    矩阵连乘

    问题描述:
    给定n个矩阵{A1,A2,…,An},其中,Ai与Ai+1是可乘的,(i=1,2 ,…,n-1)。用加括号的方法表示矩阵连乘的次序,不同的计算次序计算量(乘法次数)是不同的,找出一种加括号的方法,使得矩阵连乘的次数最小。
    比如说:A0(5 10),A1(10 100),A2(100 2)
    不同条件下:

    (A0 A1)A2 => 5*10*100+5*100*2=6000
    A0(A1 A2) => 10*100*2+5*10*2=2100

    可以看出差别还是很大的

    问题分析
    首先矩阵满足结合性,所以可以调换顺序
    将问题装换成在一个矩阵上,将各个矩阵的行列数记录在对角线上,然后根据两两相乘得到的结果,将其记录在这两个位置的上方
    不断地改变切割点,然后得到相应的值,将其放入矩阵,求出最小的值
    在这里插入图片描述
    相加得到计算量之后,建立递归关系
    在这里插入图片描述
    由此可以算出递归得到的最小值
    然后实现打印

    代码实现

    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #define MAX 50
    
    int p[MAX+1];             //存储各个矩阵的列数以及第一个矩阵的行数
    int m[MAX][MAX];          //m[i][j]存储子问题的最优解
    int s[MAX][MAX];           //s[i][j]存储子问题的最佳分割点
    int n;                    //矩阵个数
    
     void matrix(int n,int m[][n],int s[][n],int p[])
    {
    
        int i,j,k;
        for(i=0;i<n;i++)
            m[i][i]=0;                  //最小子问题仅含有一个矩阵 ,对角线全为0
    
        for(i=2;i<=n;i++)		//自底向上
            for(j=0;j<=n-i;j++)
            {
                m[j][j+i-1]=INT_MAX;
                for(k=0;k<i-1;k++)
                {                                    //k代表分割点
                    if(m[j][j+i-1]>m[j][j+k]+m[j+k+1][j+i-1]+p[j]*p[j+k+1]*p[j+i])
                    {
                        m[j][j+i-1]=m[j][j+k]+m[j+k+1][j+i-1]+p[j]*p[j+k+1]*p[j+i];
                        s[j][j+i-1]=k;                           //记录分割点
                    }
                }
            }
    }
    
     void printmatrix(int l,int r)//递归打印输出
    {
        if(l==r)
            printf("A%d",l);
        else{
            printf("(");
            printmatrix(l,l+s[l][r]);
            printmatrix(l+s[l][r]+1,r);
            printf(")");
        }
    }
    int main()
    {
        int i;
        printf("请输入矩阵相乘的矩阵个数");
        scanf("%d",&n);
        printf("请依次输入矩阵的行和列(如A*B,A=20*30,B=30*40,即输入20 30 40)
    ") ;
        for(i=0;i<=n;i++)
        {
            scanf("%d",&p[i]);
        }
        matrix(n,m,s,p);
        printf("矩阵连乘最小次数	%d
    ",m[0][n-1]);
        printmatrix(0,n-1);
        printf("
    ");
        return 0;
    }
    
    
  • 相关阅读:
    小程序登录java后端实现
    Lambda 表达式应用
    java8 实现List对象去重
    实现二:Map<Long, List<Long>> 存放的value 可能含有重复元素,将value 中含有重复元素的Map 重新组合
    实现一:多个List 可能含有重复元素,含有重复元素的集合重新组合
    SpringBoot整合rabbitMq实现消息延时发送
    spring 中aop 切面实战
    MySQL 使用AVG聚合函数时,保留两位小数的方法
    使用Java实现图片等其他文件的本地复制
    Java中初始化集合的方法
  • 原文地址:https://www.cnblogs.com/Indomite/p/14195228.html
Copyright © 2011-2022 走看看