首页 > 其他分享 >矩阵连乘--从证明到代码实现

矩阵连乘--从证明到代码实现

时间:2023-05-10 21:23:56浏览次数:34  
标签:连乘 25 12 -- 矩阵 35 计算

证明

 以下是演示与修改

 

1.  假设A1=25*12, A2=12*35, A3=35*4, A4=4*17;运行dyProg(p,n,m,s)得到的最优解为 :A1(A2*A3)A4,此时计算的乘法次数最少为4580;

2.  代码执行的过程如下:

需要计算的矩阵如下:

A1

A2

A3

A4

25×12

12×35

35×4

4×17

将其记录到一维数组之中p[5]:

p0

p1

p2

p3

p4

25

12

35

4

17

用r代表当前的矩阵链的长度,也就是子规模的问题,自下向上逐步求解,即是从链长为2的问题开始,逐步计算出链长为3,4的子问题的最优解,最终计算出四个矩阵连乘的最优解。

当 r=2 时,迭代计算出:

m[1:2] = m[1:1]+m[2:2}+p[0]*p[1]*p[2];

m[2:3] = m[2:2]+m[3:3]+p[1]*p[2]*p[3];

m[3:4] = m[3:3]+m[4][4]+p[2]*p[3]*p[4];

当 r=3 时,迭代计算出:

m[1:3]=min(m[1:1]+m[2:3]+p[0]*p[1]*p[3],m[1:2]+m[3:3]+p[0]*p[2]*p[3]);

m[2:4]=min(m[2:2]+m[3:4]+p[1]*p[2]*p[4],m[2:3]+m[4:4]+p[1]*p[3]*p[4]);

当 r=4 时,计算出最终结果:

m[1:4]=min(m[1:1]+m[2:4]+p[0]*p[1]*p[4],m[1:2]+m[3:4]+p[0]*p[2]*p[4], ,m[1:3]+m[4:4]+p[0]*p[2]*p[4]);

即:

程序结果中,第一列为i的取值,第一行为j的取值:

 3. 修改后能显示相乘顺序的代码如下:

4.    #include <stdlib.h>   
5.    #include <stdio.h>   
6.    //---------------------------------------------------------------------------   
7.    //动态创建二维数组  
8.    template<typename T>   
9.    T **creta2Darray(int n)   
10.    {   
11.        T **p = new T *[n];   
12.        for(int i=0;i<n;i++)   
13.        {   
14.        p[i]=new int[n];   
15.        for(int j=0;j<n;j++) p[i][j] = 0;   
16.        }   
17.        return p;   
18.    }   
19.    //---------------------------------------------------------------------------   
20.    //输出二维数组,屏蔽第一维  
21.    void disp2Darray(int **p,int n)   
22.    {   
23.        for(int i=1;i<n;i++)   
24.        {   
25.            for(int j=1;j<n;j++) printf("%8d",p[i][j]);   
26.            putchar('\n');   
27.        }   
28.    }   
29.    //---------------------------------------------------------------------------   
30.    //动态规划法计算矩阵连乘的最优解  
31.    void MatrixChain(int *p,int n,int **m,int **s){   
32.        for(int i=1;i<=n;i++) m[i][i] = 0;   
33.        for(int r=2;r<=n;r++)  
34.        { //r 为当前计算的链长(子问题规模)  
35.            for(int i=1;i<=n-r+1;i++)  
36.            { //n-r+1 为最后一个 r 链的前边界  
37.                int j = i+r-1; //计算前边界为 r,链长为 r 的链的后边界  
38.                //将链 ij 划分为 A(i) * ( A[i+1:j] )   
39.                m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];   
40.                s[i][j] = i; //记录断开点的索引  
41.                for(int k = i+1 ; k<j;k++)   
42.                {   
43.                    //将链 ij 划分为( A[i:k] )* (A[k+1:j])   
44.                    int t = m[i][k] + m[k+1][j] + p[i-1] *p[k]*p[j];   
45.                    if(t<m[i][j]) {  m[i][j] = t; s[i][j] = k;   }   
46.                }   
47.            }   
48.        }   
49.    }   
50.    //---------------------------------------------------------------------------  
51.    //构造最优解  
52.    void Traceback(int i,int j,int **s)   
53.    {   
54.        if(i==j) {  
55.            printf("A%d", i);  
56.            return;  
57.        }  
58.        putchar('(');  
59.        Traceback(i,s[i][j],s);   
60.        Traceback(s[i][j]+1,j,s);   
61.        putchar(')');  
62.    }  
63.    //---------------------------------------------------------------------------  
64.    //动态规划法   
65.    void dyProg(int *p,int n,int **m,int **s)   
66.    {   
67.        MatrixChain(p,n,m,s);   
68.        disp2Darray(m,n+1);   
69.        printf("\n");   
70.        disp2Darray(s,n+1);   
71.        printf("Optimal Parenthesization: ");  
72.        Traceback(1,n,s);   
73.        printf("\n");  
74.    }  
75.    //---------------------------------------------------------------------------  
76.    int main(int argc, char* argv[])   
77.    {  
78.        int p[] = {25,12,35,4,17};   
79.        int n = sizeof(p)/sizeof(int)-1;   
80.        int **m = creta2Darray<int>(n+1);   
81.        int **s = creta2Darray<int>(n+1);   
82.        //动态规划法  
83.        dyProg(p,n,m,s);   
84.        system("pause");   
85.        return 0;   
86.    }  

标签:连乘,25,12,--,矩阵,35,计算
From: https://www.cnblogs.com/yuooo/p/17389366.html

相关文章

  • 【Azure 媒体服务】Media Service的编码示例 -- 创建缩略图子画面的.NET代码调试问题
    问题描述在中国区Azure上,使用MediaService服务,想要使用.NET的代码来对上传视频创建缩略图(Thumbnail)。通过官网文档(https://docs.azure.cn/zh-cn/media-services/latest/samples/samples-encoding-reference#create-a-thumbnail-sprite)下载.NET示例,配置appsettings.json......
  • 舍罕王的失算
    ```#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<math.h>main(){   doublesum=0;      /*定义double型变量sum存放累加和*/   inti;   /*使用循环求累加和*/   for(i=1;i<=64;i++)       sum=sum+pow(2,i......
  • 三层架构 —— 具体代码
    1packagecom.itheima.web.servlet;23importcn.hutool.core.io.IoUtil;4importcom.fasterxml.jackson.databind.ObjectMapper;5importcom.itheima.domain.Student;6importcom.itheima.service.StudentService;7importcom.itheima.service.imp......
  • 乐观锁与悲观锁
    1、乐观锁乐观锁总是假设最好的情况,认为共享资源每次被访问的时候不会出现问题,线程可以不停地执行,无需加锁也无需等待,只是在提交修改的时候去验证对应的资源(也就是数据)是否被其它线程修改了(具体方法可以使用版本号机制或CAS算法)。高并发的场景下,乐观锁相比悲观锁来说,不存在锁......
  • 每日打卡-20.1
    一.问题描述编写程序提示用户输入一个班级中的学生人数n,再依次提示用户输入n个人在课程A中的考试成绩,然后计算出平均成绩,显示出来。请使用本书第9章中的数组类模板Array定义浮点型数组存储考试成绩。二.设计思路按照题目要求编写代码三.流程图四.伪代码 1五.代码......
  • Error: cannot open file: winim/lean(nim学习系列)
    某日尝试编译一个文件,报错如下。Error:cannotopenfile:winim/lean根据错误消息,需要安装“winim”,但是安装失败如下所示。cmdshell>nimbleinstallwinim--verboseReadingofficialpackagelistPrompt:winimnotfoundinanylocalpackages.json,checkin......
  • 每日打卡-20.2
    一.问题描述初始化int类型数组datal[]={1,3,5,7,9,11,13,15,17,19,2,4,6,8,10,12,14,16,18,20},应用本章的直接插入排序函数模板进行排序。对此函数模板稍做修改,加入输出语句,在每插入一个待排序元素后显示整个数组,观察排序过程中数据的变化,加深对插入排序算法的理解。二.设计思路三.流程图四.......
  • 5-10打卡 练习
    typedefstructlist{ intdata; list*next;}list;list*initlist(){ list*a=newlist; a->data=0; a->next=NULL; returna;}voidpushback(list**h,intn){list*a=newlist;a->data=n;a->next=NULL;list*......
  • textarea autosize textarea 设置高度问题
    elementui里的 textarea 高度在没有设置autosize的时候可以用属性rows='x'来设置如果设置了autosize后,rows属性就失效了,本来想着用autosize="{minRows:1,maxRows:4}",来设置高度应该是可以的,但是textarea 默认  rows='2',所以方法行不通然后想着用textarea的高度......
  • maven Unable to find a single main class
    <plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><skip>true</skip>......