• 算法设计与分析——矩阵链相乘求解


    题目描述:

    给出矩阵链相乘的最优括号次序。矩阵链A1A2A3A4A5,其维数分别为2×3,3×6,6×4,4×2,2×7。(给出计算过程)

    记住递推式:

    image.png

    由题意可得:

    image.png

    运用表格法(建议:自底向上横向填写):

    image.png

    已知数据:

    c[1,1]=0;c[2,2]=0;c[3,3]=0; c[4,4]=0; c[5,5]=0

    开始计算:

    image.png

    image.png

    image.png

    image.png

    image.png

    image.png

    image.png

    image.png

    image.png

    image.png

    最终结果:

    image.png

    填写表格:

    c[1,1]=0 c[1,2]=36 c[1,3]=84 c[1,4]=96 c[1,5]=124
    c[2,2]=0 c[2,3]=72 c[2,4]=84 c[2,5]=126
    c[3,3]=0 c[3,4]=48 c[3,5]=132
    c[4,4]=0 c[4,5]=56
    c[5,5]=0

    (1)找出这5个矩阵相乘需要的最少数量乘法的次数。
    答:c[1,5]=124

    (2)给出一个括号表达式,使得这种次序下达到乘法的次数最少。

    答:A1(A2(A3A4))A5

    C语言实现:

    #include <stdio.h>
    #include <stdlib.h>
    int m[6][6]={0};
    int s[6][6]={0};
    void Print_Optimal_Parens(int s[][6],int i,int j)  //构造最优解
    {
       if ( i ==j)
       {
           printf("A%d",i);
       }
       else
       {
           printf("(");
           Print_Optimal_Parens(s,i,s[i][j]);
           Print_Optimal_Parens(s,s[i][j]+1,j);
           printf(")");
       }
    }
    void Matrix_Chain_Order(int p[],int n)
    {
       int i,j,L,k,q;
       for (i=1;i<=n;i++)      //先对单个矩阵的链,求解,即全部m[i][i] =0;
       {
         m[i][i]=0;          
       }
       for(L=2;L<=n;L++)     //从两个矩阵链開始,逐次添加矩阵链的长度
           for(i=1;i<=n-L+1;i++)  //在给定p[]中的矩阵链中,对全部种长度为L的情况计算
           {
               j = i+L-1;
               m[i][j] = -1;
               for(k=i;k<=j-1;k++)   //遍历全部可能的划分点k。计算出最优的划分方案,
               {
                 q = m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
                 if ( q < m[i][j] || m[i][j] == -1)  
                 {
                    m[i][j] = q;     //最优的代价q保存在m[i][j]中
                    s[i][j] = k;     //最优的划分位置k保存在s[i][j]中
                 }
               }
           }
    
    }
    void main()
    {
        int p[]={2,3,6,4,2,7};    //矩阵的输入
        int length = sizeof(p)/sizeof(p[0])-1;   //矩阵长度
        int i,j;
        Matrix_Chain_Order(p,length);
    
        for(i =1;i<=5;i++)
        {
            for (j=1;j<=5;j++)
            {
                printf("%8d",m[i][j]);
            }
            printf("\n");
        }
    
        Print_Optimal_Parens(s,1,5);
        printf("\n");
    }
    

    检验结果正确!

  • 相关阅读:
    Python List comprehension列表推导式
    Git
    Python 默认参数 关键词参数 位置参数
    Blog List
    【论文笔记】DeepOrigin: End-to-End Deep Learning for Detection of New Malware Families
    【论文笔记】Malware Detection with Deep Neural Network Using Process Behavior
    Scala入门 【1】
    RocketMQ与Kafka对比(18项差异)
    Kafka简介
    Spark存储管理(读书笔记)
  • 原文地址:https://www.cnblogs.com/wangzheming35/p/15733925.html
Copyright © 2020-2023  润新知