算法导论 之 动态规划 - 矩阵链相乘

1 引言

在大学期间,我们学过高等数学中的线性规划,其中有关于矩阵相乘的章节:只有当矩阵A的列数与矩阵B的行数相等时,A×B才有意义。一个m×n的矩阵A(m,n)左乘一个n×p的矩阵B(n,p),会得到一个m×p的矩阵C(m,p)。矩阵乘法满足结合律,但不满足交换律。

假设现要计算A×B×C×D的值,因矩阵乘法满足结合律,不满足交换律,即:A、B、C、D相邻成员的相乘顺序不会影响到最终的计算结果,比如: A×(B×(C×D))、A×((B×C)×D)、(A×B)×(C×D)、A×(B×C)×D、((A×B)×C)×D,虽然组合方式不一样,但是最终的计算结果是一致的,但改变任何成员的位置将影响到最终的计算结果。

需要注意的是:虽然矩阵链相乘时,结合方式不同所得结果一致,但获得最终结果的所花费的时间是不一样的。假如:现有矩阵A(10,100)、B(100,5)、C(5,50),则不同结合方式的运算次数如下:

运算次数N1[(A×B)×C] = 10*100*5+10*5*50 = 5000 + 2500 =7500

运算次数N2[A×(B×C)] = 100*5*50 + 10*100*50 = 25000 + 50000 =75000

N1:N2 = 7500 : 75000 = 1:10,经过对比可以发现不同的结合方式在性能方面的表现相差十分明显。而《动态规划 之 矩阵链相乘》就是针对此种问题的存在,从中选择最佳的矩阵结合方式,提高此类问题的求解效率。

2 处理思路

那么针对矩阵链相乘的问题,怎样才能选出最佳的结合方式呢?那么以下将针对此问题,给出处理思路。假设现有矩阵A1(50,30)、A2(30,20)、A3(20,100)、A4(100,10)、A5(10,5),要求以最快的方式计算出它们相乘的结果。

图1 初始状态

Step1:计算相邻矩阵相乘的计算次数

N[A1×A2] = 50*30*20  = 30000

N[A2×A3] = 30*20*100 = 60000

N[A3×A4] = 20*100*10 = 20000

N[A4×A5] = 100*10*5  = 5000    - 最小

由以上的计算结果可知N[A4*A4]的值最小,因此首先结合矩阵A4(100,10)和A5(10,5),得到矩阵B(100, 5)。此时所剩矩阵为:A1(50,30)、A2(30,20)、A3(20,100)、B(100,5)。

图2 矩阵A4与A5结合

Step2:计算相邻矩阵相乘的运算次数

N[A1×A2] = 50*30*20  = 30000     - 不变

N[A2×A3] = 30*20*100 = 60000     - 不变

N[A3×B]  = 20*100*5  = 10000     - 最小

同理,结合矩阵A3和A45,得到矩阵C(20, 5)。此时所剩矩阵为:A1(50,30)、A2(30,20)、C(20,5)。

图3 矩阵A3与B结合

Step3:计算相邻矩阵相乘的运算次数

N[A1×A2] = 50*30*20 = 30000         - 不变

N[A2×C]  = 30*20*5 = 3000           - 最小

同理,结合矩阵A2和C,得到矩阵D(30, 5)。此时所剩矩阵为:A1(50,30)、D(30,5)。

图4 矩阵A2与C结合

Step4:最终计算顺序

由以上3步的统计结果可知最佳的计算方式为:A1×(A2×(A3×(A4×A5))),用树来表示计算顺序的话,其结构如下图所示:

图5 最佳计算顺序

如果需要以最快的方式计算A1*A2*A3*A4*A5的结果的话,则只需要遍历图5中的二叉树,便能找到最快的计算顺序。当然如果矩阵A1、A2、A3、A4、A5有其他的行列数时,最佳计算顺序可能为A1×((A2×A3)×(A4×A5)),则用二叉树表示为:

图6 其他可能最佳顺序

在此就暂不使用代码实现,有思路就行。

作者:邹祁峰 

2014年05月08日

算法导论 之 动态规划 - 矩阵链相乘,布布扣,bubuko.com

时间: 2024-10-25 09:41:56

算法导论 之 动态规划 - 矩阵链相乘的相关文章

算法导论之动态规划(最长公共子序列和最优二叉查找树)

动态规划师通过组合子问题的解而解决整个问题,将问题划分成子问题,递归地求解各子问题,然后合并子问题的解而得到原问题的解.和分治算法思想一致,不同的是分治算法适合独立的子问题,而对于非独立的子问题,即各子问题中包含公共的子子问题,若采用分治法会重复求解,动态规划将子问题结果保存在一张表中,避免重复子问题重复求解. 动态规划在多值中选择一个最优解,其算法设计一般分为4个步骤:描述最优解的结构:递归定义最优解的值:按自底向上的方式计算最优解的值:由计算出的结果构造一个最优解. 1)装配线调度 求解最快

算法13---动态规划矩阵链乘法

算法13---动态规划矩阵链乘法 矩阵链乘法是动态规划里面使用到的一个例子 1 两个矩阵的计算 那么对于一个矩阵的乘法,首先如果是两个矩阵的乘法,那么如何实现呢? 注意到我们使用二维数组表示矩阵,但是二维数组不能作为函数的返回值.具体实现如下 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 5 #define a_rows 3 6 #define a_columns 4 7 #define

动态规划-矩阵链乘法

问题描述: 给定由n个要相乘的矩阵构成的序列(链)<A1,A2,...,An>,要计算乘积A1A2...An,可以将两个矩阵相乘的标准算法作为一个子程序,通过加括号确定计算的顺序(对同一矩阵链,不同的计算顺序所需要的计算次数大不相同). 目标问题:给定n个矩阵构成的矩阵链<A1,A2,...,An>,其中,i=1,2,...,n,矩阵Ai的维数为pi-1×pi,对乘积A1A2...An以一种最小计算次数加全部括号. 穷尽搜索: 令P(n)表示一串n个矩阵可能的加全部方案数.当n=1

动态规划 矩阵链

算法导论上的题目,用动态规划算法解矩阵链乘法问题需要时间为O(n^3),空间为O(n^2). 问题描述: 给定n个矩阵构成的一个链(A1*A2*A3--*An),其中i=1,2,--n,矩阵Ai的维数为p(i-1)*p(i),对于乘积A1*A2*A3--*An以一种最小化标量乘法次数的方式进行加括号. /************************************************************************* > File Name: maxtrix_ch

【C++】 动态规划—矩阵链乘

[本文原创于Paul的博客园技术博客.] [本文欢迎转载,转载请以链接形式注明出处.] [本博客所有文章都经博主精心整理,请尊重我的劳动成果.] [C++] 动态规划-矩阵链乘 1.问题描述 给定n个矩阵构成的一个链给定{A1,A2,-,An},其中i=1,2,...,n.矩阵Ai的维数为pi-1*pi,如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少. 2.最优子结构 对乘积A1A2...An的任意加括号方法都会将序列在某个地方分成两部分,也就是最后一次乘法计算的

UVA 348 &amp; ZOJ 1276 Optimal Array Multiplication Sequence(dp , 矩阵链相乘问题)

Optimal Array Multiplication Sequence Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description Given two arrays A and B, we can determine the array C = AB using the standard definition of matrix multiplication: The number of

《算法导论》读书笔记之动态规划—矩阵链乘法

前言:今天接着学习动态规划算法,学习如何用动态规划来分析解决矩阵链乘问题.首先回顾一下矩阵乘法运算法,并给出C++语言实现过程.然后采用动态规划算法分析矩阵链乘问题并给出C语言实现过程. 1.矩阵乘法 从定义可以看出:只有当矩阵A的列数与矩阵B的行数相等时A×B才有意义.一个m×r的矩阵A左乘一个r×n的矩阵B,会得到一个m×n的矩阵C.在计算机中,一个矩阵说穿了就是一个二维数组.一个m行r列的矩阵可以乘以一个r行n列的矩阵,得到的结果是一个m行n列的矩阵,其中的第i行第j列位置上的数等于前一个

【算法导论】动态规划之“矩阵链乘法”问题

上一篇里,介绍了动态规划的"钢管切割"问题,这一次来看看"矩阵链乘法".所谓矩阵链乘法就是一个或一个以上的矩阵连续相乘,这里主要关注的是乘法的次数. 一.概述 以两个矩阵相乘为例,A1*A2,A1和A2为两个矩阵,假设A1的行列数是p*q,A2的行列数是q*r.注意这里由于是A1乘以A2,所以A1的列数要等于A2的行数,否则无法做矩阵乘法,满足上述条件的矩阵,我们称之为"相容"的.那么对于A1*A2而言,我们需要分别执行p*r次对应A1的行元素乘

第十五章 动态规划——矩阵链乘法

前言:今天接着学习动态规划算法,学习如何用动态规划来分析解决矩阵链乘问题.首先回顾一下矩阵乘法运算法,并给出C++语言实现过程.然后采用动态规划算法分析矩阵链乘问题并给出C语言实现过程. 1.矩阵乘法 从定义可以看出:只有当矩阵A的列数与矩阵B的行数相等时A×B才有意义.一个m×r的矩阵A左乘一个r×n的矩阵B,会得到一个m×n的矩阵C.在计算机中,一个矩阵说穿了就是一个二维数组.一个m行r列的矩阵可以乘以一个r行n列的矩阵,得到的结果是一个m行n列的矩阵,其中的第i行第j列位置上的数等于前一个