n个矩阵连乘的问题

news/2024/11/25 20:23:51/

n个矩阵连乘的问题

给定n个矩阵{A1,A2,……,An},其中Ai与Ai+1是可乘的,i=1,2,……,n-1。

例如:

计算三个矩阵连乘{A1,A2,A3};维数分别为10100 , 1005 , 5*50

按此顺序计算需要的次数((A1*A2)*A3):10X100X5+10X5X50=7500次

按此顺序计算需要的次数(A1*(A2*A3)):10X5X50+10X100X50=75000次

所以要解决的问题是:如何确定矩阵连乘积A1A2,……An的计算次序,使得按此计算次序计算矩阵连乘积需要的数乘次数达到最小化。

问题分析与描述:

两个矩阵r1r2和r2r3的矩阵相乘需r1r2r3次乘法,那么n个矩阵相乘就得到很多种不同的计算方法其中乘法最少的所花费的时间肯定最少。

那什么方法才能最快呢?

我们先了解加括号:
我们在每一个矩阵外面加一个括号,这样结果是不变的。但是当在两个矩阵外加一个括号运算方法被改变了((A1A2)A3)这两个(A1(A2A3))就是这样
然后最广到n的情况怎么不同的括号结果也就不一样了最后我们求取最快的结果即可

现在我们把这个矩阵这道题改变成加括号如何加括号才能使得最后的结果是最快的

算法设计与思路

我们将这个相乘的问题改变为加括号后我们来分析:
以6个矩阵为例:
在这里插入图片描述

这是四个矩阵和他们的维数我们先自顶向上想求取最后结果:
M1-4可以(A1)M1-3 or (A1A2)(A3A4)或者M1-3*A4
这三种情况然后M值按以下的这颗树这样向下分
我们将这个画成一棵树即为
在这里插入图片描述
最终我们在二叉树左右节点的位置求出最后小值就可得到最后答案M1-4

这里我们可以发现是需要计算很多重复值如何减少这些浪费的时间呢?

我们可以创建一个二维数组记录每一个保存的数据
用i表示行j表示列的话 Mi-j表示i到j中最小的计算次数。
当i=j时为0我们可以创建以下的二维数组m
在这里插入图片描述

最终的答案即为m[1][4]
我们在表示每次插入的括号如
在这里插入图片描述

再次建立一个二维数组com起始为0
则我们看到com【0】【2】=1我们就认为在第一个元素后加入括号A1M23
com【0】【3】=3我们在第三个矩阵后加入括号M13
A44;

伪代码:

course(int i,j)
{int u,k,t;
if(m[i][j]>=0
return m[i][j];
if(i==j) return 0;
if(i=j-1){
com[i][j+1]=i;
m[i][j]=r[i]*r[i+1]*r[i+2];
return m[i][j];}
u=course(i,i)+course(i+1,j)+r[i*r[k+1*r[j+1];
com[i][j]=i;
for(k=i+1 ;k<j;k=k+1){
t=course(i,i)+course(i+1,j)+r[i*r[k+1*r[j+1];
if(t<u){
u=t;
com[i][j]=k;
}
}
m[i][j]=u;
return u;
}

c程序

#include<stdio.h>
int m[6][6];
int com[6][6];
int r[7]={30,35,15,5,10,20,25};
int course(int i,int j){printf("i=%dj=%d\n",i,j);int u,s;if(m[i][j]>=0){return m[i][j];}if(i==j){m[i][j]=0;return 0;}if(i==j-1){m[i][j]=r[i]*r[i+1]*r[i+2];com[i][j]=i+1;return r[i]*r[i+1]*r[i+2];}printf("i=%d\n",i);u=course(i,i)+course(i+1,j)+r[i]*r[i+1]*r[j+1];com[i][j]=i+1;for(int k=i+1;k<j;k++){s=course(i,k)+course(k+1,j)+r[i]*r[k+1]*r[j+1];printf("i=%dj=%dk=%d\t%d\n",i,j,k,s);if(u>s){u=s;com[i][j]=k+1;}}m[i][j]=u;return u;
}
int main(){int n=6;for(int i=0;i<6;i++){for(int j=0;j<6;j++){m[i][j]=-1;com[i][j]=0;}}printf("最后答案%d\n",course(0,n-1));for(int i=0;i<6;i++){printf("\n");for(int j=0;j<6;j++){printf("m[%d][%d]%d\t",i,j,m[i][j]);}}for(int i=0;i<6;i++){printf("\n");for(int j=0;j<6;j++){printf("com[%d][%d]%d\t",i,j,com[i][j]);}}
}

http://www.ppmy.cn/news/824181.html

相关文章

【csdn使用小技巧】怎样用latex公式写出分子式、求和、积分、连乘符号

点赞再看&#xff0c;养成习惯&#xff0c;您动动手指对原创作者意义非凡&#x1f91d; 备战2021秋招面试 微信搜索公众号【TechGuide】关注更多新鲜好文和互联网大厂的笔经面经。 作者TechGuide 介绍 分子式 − 1 x i -\frac{1}{x_i} −xi​1​的写法如下&#xff1a; $-\f…

叉乘怎么记忆,计算

以一个例子直观记忆叉乘&#xff1a; 引用自——向量积_百度百科 (baidu.com) 在这个式子中&#xff0c;我们可以清楚地看到三项分别是i&#xff0c;j&#xff0c;k。前面则是他们的系数。我们可以直接把i&#xff0c;j&#xff0c;k看成是x&#xff0c;y&#xff0c;z&#x…

如何将两个多项式相乘

如何将两个多项式相乘 方法: 1.将乘法运算转换为加法运算 将P1当前项(ci,ei)乘P2多项式&#xff0c;再加到结果多项式中 t1 P1; t2 P2; P (Polynomial)malloc(sizeof(struct PolyNode)); P->link NULL; Rear P; while(t2){Attach(t1->coef*t2->coef,t1->e…

叉乘公式

叉乘公式 注意别加绝对值&#xff0c;左旋和右旋的正负不一样&#xff0c;面积的加减不一样&#xff0c;否则会有重复的 #include<stdio.h> #include<math.h> int main(void) {int n,i,j;double x[105][3],x1,y1,a,b,c,d;while(scanf("%d",&n)!0){d…

多项式求积符号

求积符号&#xff08;∏&#xff09;的读音是pai ∏是希腊字母&#xff0c;即π的大写形式&#xff0c;在数学中表示求积运算或直积运算&#xff0c;形式上类似于Σ ∏&#xff0c;读作”派”&#xff0c;即π的大写、是求积符号&#xff0c;累项相乘。1、用法&#xff1a;上下…

矩阵连乘

给定n个矩阵&#xff1a;A1,A2,...,An&#xff0c;其中Ai与Ai1是可乘的&#xff0c;i1&#xff0c;2...&#xff0c;n-1。确定计算矩阵连乘积的计算次序&#xff0c;使得依此次序计算矩阵连乘积需要的数乘次数最少。输入数据为矩阵个数和每个矩阵规模&#xff0c;输出结果为计算…

一篇万字博客带你入门layUI

今日金句 心里种花&#xff0c;人生才不会荒芜 文章目录 一、什么是layui二、layui、easyui与bootstrap的对比2.1 layui和bootstrap对比&#xff08;这两个都属于UI渲染框架&#xff09;2.2 layui和easyui对比 三、layui入门3.1 引入3.2 入门案例&#xff1a;点击弹出框3.3 经…

基于matlab从ROI和蒙版在图像中创建标记(附源码)

一、前言 此示例演示如何从一组 ROI 创建标记的阻止映像。 在此示例中&#xff0c;您使用两种方法来获取和显示标记的数据。一种方法使用多边形ROI对象来存储肿瘤和正常组织区域边界的坐标。该函数将ROI坐标转换为标记的块图像。第二种方法使用掩码来指示图像的二进制分割为组…