矩阵连乘(数据结构)

合集下载

矩阵连乘问题的算法

矩阵连乘问题的算法

矩阵连乘问题的算法

一、矩阵连乘问题

矩阵连乘问题是指在矩阵计算中,给定n个矩阵,求这n个矩阵的连乘积的最优解问题。矩阵连乘问题既可以用于组合优化,也可以用于信息处理系统中查找最优路径的搜索算法。它是最基本的组合优化问题。

二、矩阵连乘问题的算法

1. 动态规划法:动态规划法是求解矩阵连乘问题的常用算法。它采用递归方法,将原问题分解为若干个子问题,然后求出各子问题的最优解,最后组合出原问题的最优解。

2. 贪心算法:贪心算法是一种经典的最优化算法,也可以用于求解矩阵连乘问题,即通过某种启发式规则,在每一步中都使最优决策,最终得到最优解。

3. 分支定界法:分支定界法是一种由搜索算法和界定法相结合而成的最优化算法,也可以用于求解矩阵连乘问题。该算法按照树状的层次结构,向下搜索一个在每一步骤都使得当前最优的路径,然后上溯形成最优解。

4. 模拟退火算法:模拟退火算法是一种搜索算法,它可以用于求解矩阵连乘问题。它采用一种模拟物理过程的原理,通过不断地改变解的状态,以求出相对最优解。

- 1 -

矩阵连乘题目

矩阵连乘题目

矩阵连乘题目

摘要:

一、矩阵连乘的定义和性质

1.矩阵连乘的概念

2.矩阵连乘的性质

二、矩阵连乘的计算方法

1.矩阵乘法的运算法则

2.矩阵连乘的计算步骤

三、矩阵连乘在实际问题中的应用

1.图像处理

2.机器学习

四、矩阵连乘的优化方法

1.矩阵分解

2.矩阵压缩

正文:

矩阵连乘是线性代数中的一个重要概念,它涉及到矩阵的乘法运算。矩阵连乘不仅具有自身的性质,还在许多实际问题中有着广泛的应用。本文将介绍矩阵连乘的定义、性质,计算方法,以及在实际问题中的应用和优化方法。

一、矩阵连乘的定义和性质

矩阵连乘是指将两个矩阵相乘得到一个新的矩阵。设矩阵A 为m×n 矩阵,矩阵B 为n×p 矩阵,则矩阵C=AB 为m×p 矩阵。矩阵连乘有一个

重要的性质,即结合律,满足(AB)C=A(BC)。

二、矩阵连乘的计算方法

矩阵连乘的计算方法主要依赖于矩阵乘法的运算法则。设矩阵A 为m×n 矩阵,矩阵B 为n×p 矩阵,矩阵C 为m×p 矩阵,则有:

1.元素级运算:C[i,j] = ΣA[i,k] * B[k,j]

2.行级运算:C[i,:] = A[i,:] * B

3.列级运算:C[:,j] = A * B[:,j]

三、矩阵连乘在实际问题中的应用

矩阵连乘在实际问题中有着广泛的应用,例如图像处理、机器学习等领域。在图像处理中,矩阵连乘常用于图像的缩放、旋转等操作。在机器学习中,矩阵连乘则可以用于计算特征向量之间的相似性。

四、矩阵连乘的优化方法

矩阵连乘在实际应用中,往往涉及到大规模矩阵的运算,因此需要优化计算方法以提高效率。常见的优化方法包括矩阵分解和矩阵压缩。矩阵分解可以将矩阵分解为若干个矩阵的乘积,从而降低计算复杂度。矩阵压缩则可以通过压缩矩阵的存储空间,减少计算过程中的内存消耗。

excel矩阵连乘公式

excel矩阵连乘公式

excel矩阵连乘公式

Excel矩阵连乘公式是在Excel中使用的一种数学计算公式,用于计算多个矩阵相乘的结果。通过利用这个公式,我们可以快速、准确地计算矩阵连乘的结果,从而简化复杂的数学运算。

在Excel中,我们可以使用矩阵连乘公式来计算任意数量的矩阵相乘。这个公式的基本形式为:=MMULT(矩阵1, 矩阵2, 矩阵3, …)。其中,矩阵1、矩阵2、矩阵3等代表要相乘的矩阵,可以是任意大小的矩阵。

使用矩阵连乘公式进行计算时,需要注意以下几点:

1. 矩阵的维度必须满足相乘的要求。具体而言,矩阵1的列数必须等于矩阵2的行数,矩阵2的列数必须等于矩阵3的行数,以此类推。

2. 通过在Excel中输入矩阵数据,并使用矩阵连乘公式,可以快速计算出结果。Excel会自动将矩阵连乘公式应用到每个单元格中,得到相应的计算结果。

3. 在进行矩阵连乘计算时,可以通过调整矩阵的顺序,得到不同的结果。这是因为矩阵相乘不满足交换律,即A*B不一定等于B*A。

4. 当需要计算多个矩阵相乘时,可以通过将矩阵连乘公式嵌套使用,实现多个矩阵的连乘计算。

矩阵连乘公式的应用十分广泛。在工程、物理学、经济学等领域,

矩阵连乘公式常常被用于解决实际问题。例如,在网络分析中,可以使用矩阵连乘公式计算节点之间的关系;在金融领域,可以使用矩阵连乘公式计算投资组合的收益率。

Excel矩阵连乘公式是一种强大的数学工具,可以帮助我们快速、准确地计算多个矩阵的相乘结果。通过合理运用这个公式,我们可以简化复杂的数学运算,提高工作效率。无论是在学习、工作还是研究中,掌握矩阵连乘公式都是非常有用的。希望本文对读者能够有所帮助,更好地理解和应用Excel矩阵连乘公式。

矩阵连乘问题(动态规划算法)

矩阵连乘问题(动态规划算法)

矩阵连乘问题(动态规划算法)

动态规划算法思想简介:

将⼀个问题分解为多个⼦问题,这点和分治法类似,但是每个⼦问题不是独⽴的⽽是相互联系的,所以我们在求解每个⼦问题的时候可能需要重复计算到其他的⼦问题,所以我们将计算过的⼦问题的解放进⼀个表中,这样就能避免了重复计算带来的耗费,这就是动态规划的基本思想;

⼀般地,动态规划思想⼀般⽤来解最优化问题,主要分为以下四个步骤:

(1)找出最优解的性质,并刻画其结构特征;

(2)递归地定义最优值;

(3)以⾃底向上的⽅式计算出最优值;

(4)根据计算得到的最优值时得到的信息,构造最优解;

同时,问题的最优⼦结构性质也是该问题可⽤动态规划算法求解的显著特征,这⾥的最优⼦结构性质即指:问题的最优解也即代表着它的⼦问题有了最优解;

问题描述:

分析过程如下:

(1)分析最优⼦结构的性质:

(2)分析递归关系,以及利⽤⾃底向上的⽅式进⾏计算:

(3)获取最优值和最优解:

代码如下:

#ifndef MATRIX_CHAIN_H

#define MATRIX_CHAIN_H

void matrix_chain(int *p, int n, int **m, int **s);

void traceback(int i, int j, int **s);

#endif

#include <iostream>

#include "matrix_chain.h"

using namespace std;

//利⽤动态规划算法获取最优值

void matrix_chain(int *p, int n, int **m, int **s) //p:各个矩阵的列数,n:矩阵个数,m:m[i:j]矩阵i到j的相乘次数,s:对应的分开位置

矩阵连乘问题

矩阵连乘问题

矩阵连乘问题

目录:

矩阵连乘问题:

1. 描述矩阵连乘问题

2. 分析矩阵连乘问题以及对递归式的推导(1)直接递归思路

(2)备忘录思路

(3)动态规划思路

3. 伪代码的方式描述算法:

(1)直接递归算法

(2)备忘录算法

(3)动态规划算法

4. 把算法转换成程序实现的过程及结果(1)直接递归算法程序

(2)备忘录算法程序

(3)动态规划算法程序

1.描述矩阵连乘问题:

,其中i A和1+i A是可乘的,给定n个矩阵{n A

A

A⋯

,2

,1}

i=1,2,…,n-1。考察这n个矩阵的连乘积n A

A

A⋯

,1。

,2

由于矩阵乘法具有结合律,故计算矩阵的连乘积可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。若一个矩阵连乘积的计算次序完全确定,也就是说连乘积已完全加括号,则可依次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积。完全加括号的矩阵连乘可递归地定义为:(1)单个矩阵是完全加括号的;(2)矩阵连乘积A是完全加括号的,则A可表示为2个完全加括号的矩阵连乘B和C的乘积并加括号,即A=(BC)。

矩阵A和B可乘的条件是矩阵A的列数等于矩阵B的行数。若A是一个p×q的矩阵,B 是一个q×r的矩阵,那么C=A×B就是一个p ×r矩阵。它的计算是三重循环的,计算量是pqr。如果加括号后矩阵的量是不同的,所以我们的问题就是要讨论如何给连乘的矩阵加括号

才能使矩阵的计算量最少。

穷举搜索法:对于n 个矩阵的连乘积,设有不同的计算次序P(n)。由于可以先在第k 个和第k+1个矩阵之间将原矩阵序列分为两个矩阵子序列,k=1,2,...,n-1;然后分别对这两个矩阵子序列完全加括号;最后对所得的结果加括号,得到原矩阵序列的一种完全加括号方式。由此可得P(n)的递归式如下:

矩阵连乘matlab

矩阵连乘matlab

矩阵连乘matlab

在Matlab中,可以使用矩阵乘法运算符``来进行矩阵的连乘操作。下面我将从多个角度来解答你关于矩阵连乘的问题。

首先,让我们了解一下矩阵连乘的基本概念。矩阵连乘是指将

多个矩阵相乘的操作。假设我们有n个矩阵A1, A2, ..., An,它

们的维度分别为m1×m2, m2×m3, ..., mn-1×mn。矩阵连乘的结

果为A1×A2×...×An,维度为m1×mn。

在Matlab中,我们可以使用``运算符来实现矩阵连乘。假设我

们有三个矩阵A、B和C,我们可以使用`ABC`来计算它们的连乘结果。

除了使用``运算符,Matlab还提供了一些其他的函数来进行矩

阵连乘。其中一个常用的函数是`mtimes`,它可以用来计算两个矩

阵的乘积。例如,`mtimes(A, B)`将计算矩阵A和B的乘积。

另外,如果你有多个矩阵需要连乘,可以使用循环结构来实现。例如,假设我们有一个包含n个矩阵的单元格数组M,你可以使用

循环来计算它们的连乘结果。下面是一个示例:

result = M{1};

for i = 2:length(M)。

result = result M{i};

end.

在这个示例中,我们首先将结果初始化为第一个矩阵M{1},然

后使用循环将后续的矩阵依次乘上去。最终,result将保存连乘的

结果。

此外,Matlab还提供了一些其他的函数来处理矩阵连乘的问题。例如,`mpower`函数可以用来计算矩阵的幂,`kron`函数可以用来

计算克罗内克积。

总结起来,Matlab提供了多种方法来进行矩阵连乘操作,包括

数据结构 第4章 矩阵乘法

数据结构 第4章 矩阵乘法

b12 b22 b32 b42
b13
b23
C
b33
b43
A*B
c11 c21 c31
c12 c22 c32
c13
c23
c33
cij aik bkj ai1b1 j ai2b2 j ai3b3 j ai4b4 j , i 1,2,3, j 1,2,3
k 1
为求得Q的第i行,按此次序计算乘积项aikbkj
4
cij aik bkj ai1b1 j ai2b2 j ai3b3 j ai4b4 j , i 1,2,3, j 1,2,3 k 1
2
矩阵相乘的经典算法
两个矩阵相乘的经典算法若设C=A*B其中,A是m1*n1 矩阵,B是m2*n2矩阵。当n1=m2时有:
for (i=1;i<m1; ++i ) for ( j=1; j<=n2; ++j){ C[i][j]=0; for(k=1; k<=n1; ++k) C[i][j]+=A[i][k]*B[k][j]; }
k 1
为求得Q的第i行,按此次序计算乘积项aikbkj
ci1 ai1b11 ai2b21 ai3b31 ai4b41 ci2 ai1b12 ai2b22 ai3b32 ai4b42 ci3 ai1b13 ai2b23 ai3b33 ai4b43

矩阵连乘算法

矩阵连乘算法

输入矩阵A

输入矩阵B

输出矩阵C=(A*B)

代码:

#include

#define MAX 32

int martixminus(int a[][MAX],int b[][MAX],int c[][MAX],int s) {

int i,j;

for(i=0;i

{

for(j=0;j

c[i][j]=a[i][j]-b[i][j];

}

return 0;

}

int martixadd(int a[][MAX],int b[][MAX],int c[][MAX],int s) {

int i,j;

for(i=0;i

{

for(j=0;j

c[i][j]=a[i][j]+b[i][j];

}

return 0;

}

int part(int a[][MAX],int a11[][MAX],int a12[][MAX],int

a21[][MAX],int a22[][MAX],int s)

{

int i,j,k;

k=s/2;

for(i=0;i

{

for(j=0;j

{

a11[i][j]=a[i][j];

a12[i][j]=a[i][j+k];

a21[i][j]=a[i+k][j];

a22[i][j]=a[i+k][j+k];

}

}

return 0;

}

int Strassen(int a[][MAX],int b[][MAX],int c[][MAX],int s)

{

int A11[MAX][MAX],A12[MAX][MAX],A21[MAX][MAX],A22[MAX][MAX], B11[MAX][MAX],B12[MAX][MAX],B21[MAX][MAX],B22[MAX][MAX],

邻接矩阵的乘法

邻接矩阵的乘法

邻接矩阵的乘法

邻接矩阵是图论中最基本的数据结构之一,它用于表示有向图和无向图中的顶点和边。邻接矩阵乘法是计算两个邻接矩阵相乘的算法,它在图论和计算机科学领域中都有广泛应用。本文将详细介绍邻接矩阵乘法的概念、实现方法和应用场景。

一、概念

1. 邻接矩阵

邻接矩阵是一个二维数组,其中每个元素表示两个顶点之间是否存在一条边。对于无向图而言,邻接矩阵是一个对称矩阵;对于有向图而言,邻接矩阵则不一定是对称的。

2. 邻接矩阵乘法

邻接矩阵乘法是指将两个有向图或无向图的邻接矩阵相乘得到一个新的邻接矩阵。在计算机科学中,通常使用这种方法来计算两个图之间的路径或者连接关系。

二、实现方法

1. 常规算法

常规的邻接矩阵乘法算法需要进行三重循环操作。具体来说,就是先

将第一个邻接矩阵的每一行和第二个邻接矩阵的每一列相乘,然后将

结果相加得到新的邻接矩阵。这种算法的时间复杂度为O(n^3)。

2. Strassen算法

Strassen算法是一种优化的邻接矩阵乘法算法,它将三重循环操作转

换成了七个子问题。通过递归调用自身来解决这些子问题,可以将时

间复杂度降低到O(n^2.81)。

3. Coppersmith-Winograd算法

Coppersmith-Winograd算法是目前已知的最快的邻接矩阵乘法算法,它将时间复杂度降低到了O(n^2.376)。该算法使用了分治和线性代数的技巧,并且需要大量的预处理和内存空间。

三、应用场景

1. 图论中的最短路径问题

在图论中,最短路径问题是指找到两个顶点之间距离最短的路径。通

过使用邻接矩阵乘法可以计算出两个图之间所有可能的路径,并且找

矩阵连乘算法

矩阵连乘算法

福州大学数学与计算机科学学院

《计算机算法设计与分析》上机实验报告(2)

i<=k<j,则:m[i][j]=m[i][k]+m[k+1][j]+pi-1pkpj。由于在计算是并不知道断开点k 的位置,所以k还未定。不过k的位置只有j-i个可能。因此,k是这j-i个位置使计算量达到最小的那个位置。

综上,有递推关系如下:

若将对应m[i][j]的断开位置k记为s[i][j],在计算出最优值m[i][j]后,可递归地由s[i][j]构造出相应的最优解。s[i][j]中的数表明,计算矩阵链A[i:j]的最佳方式应在矩阵Ak和Ak+1之间断开,即最优的加括号方式应为

(A[i:k])(A[k+1:j)。从s[1][n]记录的信息可知计算A[1:n]的最优加括号方式为

(A[1:s[1][n]])(A[s[1][n]+1:n]),进一步递推,A[1:s[1][n]]的最优加括号方式为

(A[1:s[1][s[1][n]]])(A[s[1][s[1][n]]+1:s[1][s[1][n]]])。同理可以确定A[s[1][n]+1:n]的最优加括号方式在s[s[1][n]+1][n]处断开...照此递推下去,最终可以确定

A[1:n]的最优完全加括号方式,及构造出问题的一个最优解。3、动态规划迭代算法设计:

用动态规划迭代方式解决此问题,可依据其递归式自底向上的方式进行计算。在计算过程中,保存已解决的子问题的答案。每个子问题只计算一次,而在后面需要时只需简单检查一下,从而避免了大量的重复计算,最终得到多项式时间的算法。

数据结构_矩阵的相乘

数据结构_矩阵的相乘

# include <iostream>

# define MAXSIZE 20

using namespace std;

typedef struct //三元组的定义

{

int row; //非0元的行下标

int col; //非0元的列下标

int e; //非0元的素值

}Triple;

typedef struct //矩阵的定义

{

Triple data[MAXSIZE]; //非0元三元组表

int m,n,len; //矩阵的行数,列数和非0元个数

}TSMatrix;

void initMatrix(TSMatrix &A) //矩阵初始化函数,参数类型为矩阵

{

A.len=0;

A.m=0;

A.n=0;

for (int i=0; i<MAXSIZE;i++)

{

A.data[i].col=0;

A.data[i].e=0;

A.data[i].row=0;

}

}

void createMatrix(TSMatrix &A) //创建矩阵函数,创建三元组顺序表表示的矩阵

{

initMatrix(A);

cout<<"创建矩阵:";

cout<<"请输入矩阵的行、列值及非0元的个数:\n";

cin>>A.m>>A.n>>A.len; //输入矩阵的行、列值及非0元的个数for(int i=0;i<A.len;i++) //循环输入非0元的值

{

cout<<"请输入第:" <<i+1 <<" 非0元素对应的行、列、值:\n";

矩阵连乘问题方程

矩阵连乘问题方程

矩阵连乘问题方程

矩阵连乘问题是一个经典的优化问题,涉及到多个矩阵的乘法操作。为了提高计算效率,我们需要找到一种最优的矩阵乘法顺序,使得计算成本最低。

假设我们有一组矩阵A1, A2, ..., An,它们需要进行连乘操作,即C = A1 * A2 * ... * An。我们需要找到一种最优的乘法顺序,使得计算矩阵C 的成本最低。根据矩阵乘法的性质,我们可以知道以下规律:

1. 矩阵的乘法满足结合律,即(A * B) * C = A * (B * C)。

2. 矩阵的乘法不满足交换律,即A * B 不一定等于B * A。

因此,我们不能简单地将矩阵按照任意顺序进行连乘,而是需要寻找一种最优的乘法顺序。

一种常见的解决方法是使用动态规划算法。我们可以定义一个二维数组dp[i][j],表示前i 个矩阵进行连乘,最终得到矩阵j 的最小计算成本。然后我们遍历所有可能的矩阵乘法顺序,更新dp 数组的值。最终,dp[n][j] 的值就是我们要求的最小计算成本。

下面是具体的算法步骤:

1. 初始化dp 数组为一个n 行j 列的全零数组。

2. 遍历所有可能的矩阵乘法顺序,对于每个顺序,计算当前乘法操作的成本,并更新dp 数组的值。

3. 最后,dp[n][j] 的值就是我们要求的最小计算成本。

需要注意的是,由于矩阵的维度可能很大,导致可能的矩阵乘法顺序非常多,因此这个问题的计算复杂度是非常高的。在实际应用中,我们通常会使用一些启发

式算法来近似最优解。

矩阵连乘问题的算法

矩阵连乘问题的算法

矩阵连乘问题的算法

介绍

矩阵连乘问题是一个经典的数学问题,它涉及到如何寻找一组矩阵相乘的最优顺序,使得计算所需的乘法操作总数最小化。这个问题在计算机科学和算法设计中有着重要的应用。本文将介绍矩阵连乘问题的算法及其相关概念和应用。

问题描述

给定一组矩阵{A1, A2, A3, …, An},其中Ai的维度为pi-1 × pi(1 ≤ i ≤ n),我们希望找到一种矩阵相乘的顺序,使得计算这些矩阵相乘所需的乘法操作

总数最小化。

动态规划算法

动态规划算法是解决矩阵连乘问题的经典方法。它通过存储中间结果来避免重复计算,从而提高计算效率。下面将介绍动态规划算法的具体实现步骤。

定义子问题

假设我们要计算矩阵Ai × Ai+1 × … × Aj的最优顺序和乘法操作总数,其中

i ≤ j。

确定状态转移方程

设m[i][j]表示计算矩阵Ai × Ai+1 × … × Aj的最优顺序和乘法操作总数。

根据定义,我们有以下状态转移方程: - 当i = j时,m[i][j] = 0,因为只有一个矩阵无需进行乘法操作; - 当i < j时,m[i][j] = min{m[i][k] + m[k+1][j] + pi-1 × pk × pj},其中i ≤ k < j。

填表计算最优值

根据状态转移方程,我们可以使用动态规划的方法逐步填充表格m。具体步骤如下:1. 初始化所有m[i][i]为0(0 ≤ i ≤ n); 2. 对于每个子问题(i, j),从i

= 1递增到j = n-1,按照递增的长度进行计算: - 对于每个i和j,根据状态转移方程计算m[i][j]; 3. 最终,m[1][n-1]即为所求的计算矩阵Ai × Ai+1

矩阵连乘和strassen矩阵乘法

矩阵连乘和strassen矩阵乘法

矩阵连乘和strassen矩阵乘法

矩阵连乘问题和 Strassen 矩阵乘法是计算机科学中的两个重要问题。矩阵常常被用来表示线性算法问题,而矩阵的乘法则是表示两个矩阵之间运算的一种方法。本文将对这两个问题分别进行介绍,以便更深入地了解矩阵的应用和计算方法。

矩阵连乘问题

矩阵连乘问题是指给定一组矩阵,求其乘积的最小计算次数,并构造出相应的计算方法。在算法中,我们通常采用递归的思想来解决这个问题。递归过程中,我们根据矩阵的大小将矩阵划分成更小的子矩阵,然后再对这些子矩阵进行计算。

设矩阵连乘的矩阵序列为 A1, A2, A3, ..., An,其中矩阵 Ai 的行数和列数分别为 pi - 1 和 pi。那么,计算这个矩阵序列的最小计算次数可以表示为递推式:

m[i,j] = min{m[i,k] + m[k+1,j] + pi-1 * pk * pj} (i <= k < j)

这个式子的意思是将矩阵序列Ai, Ai+1,...,Aj-1, Aj划分为两个子序列Ai, Ai+1,...,Ak和Ak+1,...,Aj,然后在这两个子序列中分别计算矩阵乘积所需的最小计算次数,其中pi-1 * pk * pj表示计算Ai到Aj乘积时需要的乘法次数。由此,我们可以得出矩阵连乘的递归算法:

Matrix Chain Multiply(A, p, i, j)

if i == j

return A[i]

else

k = i

M = Matrix Chain Multiply(A, p, i, k)

N = Matrix Chain Multiply(A, p, k+1, j)

n个矩阵连乘问题

n个矩阵连乘问题

矩阵连乘问题是一个经典的优化问题,其目标是在给定一组矩阵和它们之间的乘法顺序下,找出最少的括号方案数,使得乘法操作可以按照给定的顺序进行。

假设有n个矩阵A1, A2, ..., An,我们需要计算它们的连乘积。每个矩阵Ai都有m×m的元素。

矩阵连乘问题可以转化为以下动态规划问题:

1. 定义dp[i][j]为计算矩阵Ai到Aj的连乘积所需的最少括号方案数。

2. 初始化dp[i][i]=0,表示单个矩阵不需要任何括号。

3. 对于i<j,计算dp[i][j]的递推关系:

dp[i][j] = dp[i][k] + dp[k+1][j] + p[i-1]*p[k]*p[j],其中k=i,...,j-1。

其中p是任意一个正整数,表示矩阵的维度m。

4. 最终答案为dp[1][n]。

以下是Python代码实现:

计算结果为:最少需要15个括号方案数。

典型的动态规划举例矩阵连乘问题

典型的动态规划举例矩阵连乘问题
一、典型的动态规划举例——矩阵连乘问题
作为经典的动态规划算法举例, 矩阵连乘问题很好地展现了动态规划的特点和实用价值。 给 定 n 个矩阵{A1,A2,...,An},其中 Ai 与 Ai+1 是可乘的,i=1,2,...n-1。现在要计算这 n 个矩阵的 连乘积。 由于矩阵的乘法满足结合律, 所以通过加括号可以使得计算矩阵的连乘积有许多不 同的计算次序。然而采用不同的加扩号方式,所需要的总计算量是不一样的。若 A 是一个 p*q 矩阵,B 是一个 q*r 矩阵,则其乘积 C=AB 是一个 p*r 矩阵。如果用标准算法计算 C, 总共需要 pqr 次数乘。 现在来看一个例子。 A1, A2, A3 分别是 10*100,100*5 和 5*50 的矩阵。 如果按照((A1A2)A3) 来计算, 则计算所需的总数乘次数是 10*100*5+10*5*50=7500。 如果按照(A1(A2A3))来计算, 则需要的数乘次数是 100*5*50+10*100*50=75000,整整是前者的 10 倍。由此可见,在计算 矩阵连乘积时, 不同的加括号方式所导致的不同的计算对计算量有很大的影响。 如何确定计 算矩阵连乘积 A1A2,...,An 的一个计算次序,使得依此次序计算矩阵连乘积需要的数乘次 数最少便成为一个问题。 对于这个问题, 穷举法虽然易于入手, 但是经过计算, 它所需要的计算次数是 n 的指数函数, 因此在效率上显得过于低下。 现在我们按照动态规划的基本步骤来分析解决这个问题, 并比 较它与穷举法在时间消耗上的差异。 (1)分析最优解的结构。 现在,将矩阵连乘积 AiAi+1...Aj 简记为 A[i:j]。对于 A[1:n]的一个最优次序,设这个计算次 序在矩阵 Ak 和 Ak+1 之间将矩阵链断开(1<=k<n),那么完全加括号的方式为 ((A1...Ak)(Ak+1...An))。依此次序,我们应该先分别计算 A[1:k]和 A[k+1:n],然后将计算结 果相乘得到 A[1:n],总计算量为 A[1:k]的计算量加上 A[k+1:n]的计算量,再加上 A[1:k]和 A[k+1:n]相乘的计算量。 通过反证法可以证明,问题的关键特征在于,计算 A[1:n]的一个最优次序所包含的计算矩阵 子链 A[1:k]和 A[k+1:n]的次序也是最优的。因此,矩阵连乘积计算次序问题的最优解包含着 其子问题的最优解。这种最优子结构性质是该问题可以用动态规划解决的重要特征。 (2)建立递归关系定义最优值。 设计算 A[i:j](1<=i<=j<=n)所需的最少数乘次数为 m[i][j],则原问题的最优值为 m[1][n]。而 且易见,当 i=j 时,m[i][j]=0。 根据上述最优子结构性质,当 i<j 时,若计算 A[i:j]的最优次序在 Ak 和 Ak+1 之间断开,可 以定义 m[i][j]=m[i][k]+m[k+1][j]+pi-1*pk*pj(其中,Ai 的维数为 pi-1*pi)。从而有:
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

动态规划——矩阵连乘的问题

《问题的引出》

看下面一个例子,计算三个矩阵连乘{A1,A2,A3};维数分别为10*100 , 100*5 , 5*50

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

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

所以问题是:如何确定运算顺序,可以使计算量达到最小化。

枚举显然不可,如果枚举的话,相当于一个“完全加括号问题”,次数为卡特兰数,卡特兰数指数增长,必然不行。

《建立递归关系》

子问题状态的建模(很关键):令m[i][j]表示第i个矩阵至第j个矩阵这段的最优解。

显然如果i=j,则m[i][j]这段中就一个矩阵,需要计算的次数为0;

如果i>j,则m[i][j]=min{m[i][k]+m[k+1][j]+p[i-1]Xp[k]Xp[j]},其中k,在i与j 之间游荡,所以i<=k

代码实现时需要注意的问题:计算顺序!!!

因为你要保证在计算m[i][j]查找m[i][k]和m[k+1][j]的时候,m[i][k]和m[k+1][j]已经计算出来了。

观察坐标的关系如图:

所以计算顺序如上右图:相应的计算顺序对应代码为13-15行

m[1][n]即为最终求解,最终的输出想为((A1(A2 A3))((A4 A5)A6))的形式,不过没有成功,待思考...

1#include

2using namespace std;

3const int MAX = 100;

4//p用来记录矩阵的行列,main函数中有说明

5//m[i][j]用来记录第i个矩阵至第j个矩阵的最优解

6//s[][]用来记录从哪里断开的才可得到该最优解

7int p[MAX+1],m[MAX][MAX],s[MAX][MAX];

8int n;//矩阵个数

9

10void matrixChain(){

11for(int i=1;i<=n;i++)m[i][i]=0;

12

13for(int r=2;r<=n;r++)//对角线循环

14for(int i=1;i<=n-r+1;i++){//行循环

15int j = r+i-1;//列的控制

16 //找m[i][j]的最小值,先初始化一下,令k=i

17 m[i][j]=m[i][i]+m[i+1][j]+p[i-1]*p[i]*p[j];

18 s[i][j]=i;

19//k从i+1到j-1循环找m[i][j]的最小值

20for(int k = i+1;k

21int temp=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];

22if(temp

23 m[i][j]=temp;

24//s[][]用来记录在子序列i-j段中,在k位置处

25 //断开能得到最优解

26 s[i][j]=k;

27 }

28 }

29 }

30}

31

32//根据s[][]记录的各个子段的最优解,将其输出

33void traceback(int i,int j){

34if(i==j)return ;

35

36 traceback(i,s[i][j]);

37 traceback(s[i][j]+1,j);

38 cout<<"Multiply A"<

40

41int main(){

42 cin>>n;

43for(int i=0;i<=n;i++)cin>>p[i];

44//测试数据可以设为六个矩阵分别为

45 //A1[30*35],A2[35*15],A3[15*5],A4[5*10],A5[10*20],A6[20*25]

46 //则p[0-6]={30,35,15,5,10,20,25}

47 //输入:6 30 35 15 5 10 20 25

48 matrixChain();

49

50 traceback(1,n);

51//最终解值为m[1][n];

52 cout<

53return0;

54}

相关文档
最新文档