动态规划解决矩阵连乘问题(C++实现)

1.       采用标准的矩阵乘法来计算M1M2M3三个矩阵的乘积M1M2M3,设这三个矩阵的维数分别是2 × 10、10 × 2和2 × 10。如果先把M1M2相乘,然后把结果和M3相乘,那么要进行2× 10 × 2 + 2 × 2 × 10 = 80次乘法;如果代之用M2M3相乘的结果去乘M1,那么数量乘法的次数为10× 2 × 10 + 2 × 10 × 10 = 400。显然,执行乘法M1(M2M3)耗费的时间是执行乘法(M1M2)M3的5倍。一般来说,n个矩阵M1M2……Mn链乘法的耗费,取决于n– 1个乘法执行的顺序,请设计一个动态规划算法,使得计算矩阵链乘法时需要的数量乘法次数达到最小。

矩阵

M1

M2

M3

M4

M5

M6

维数

30 × 35

35 × 15

15 × 5

5 × 10

10 × 20

20 × 25



由于问题中存在大量的重叠子问题,使用分治算法递归得出结果的效率并不高,因此可以使用动态规划来解决。首先创建一个函数functionD(参数为p数组:用于存放矩阵的行列数,n:矩阵的规模,二维数组m用来存放指定范围矩阵相乘的次数最小值,二维数组s:用于存放指定范围矩阵的最佳断开位置),首先使用for循环将单个矩阵相乘的次数设为零,其次通过使用for循环来控制矩阵的规模,使其规模递增,在一个规模里将默认的断点设为第一个矩阵处断开,其次再使用for循环控制断点的移动,然后通过if语句来得出是否为最佳断点。当所有规模都循环结束时,得到的m[i][n]便是整个矩阵链的最短乘法次数。

#include 

using namespace std;


 void functionD(int *p,int n,int **m,int **s) {
	for (int i=1 ; i <= n; i++){
		m[i][i]=0;//将单个矩阵相乘的次数设为0 
	} 
	for(int r=2 ; r <= n; r++) {//r为矩阵链的规模 
		for(int i=1; i<=n-r+1;i++){//i为前边界 
			int j=i+r-1;//j为后边界 
			m[i][j]=m[i][i]+m[i+1][j]+p[i-1]*p[i]*p[j];//记录断点在i处时所需要的乘法次数 
			s[i][j]=i;//将断点初始化在i处 
			for(int k=i+1;k

你可能感兴趣的:(动态规划解决矩阵连乘问题(C++实现))