Dynamic programming to solve the matrix multiplication problem (C++ implementation)

1. Use standard matrix multiplication to calculate the product M 1 M 2 M 3 of the three matrices M 1 , M 2 and M 3 , where the dimensions of these three matrices are 2 × 10, 10 × 2, and 2 × 10, respectively . If M 1 and M 2 are multiplied first, and then the result is multiplied by M 3 , then 2 × 10 × 2 + 2 × 2 × 10 = 80 multiplications; if instead we multiply M 2 and M 3 Multiply the result of M 1 , then the number of times of multiplication is 10 × 2 × 10 + 2 × 10 × 10 = 400. Obviously, the time it takes to perform the multiplication M 1 ( M 2 M 3 ) is to perform the multiplication ( M 1 M 2 )5 times the M3 . Generally speaking, the cost of chain multiplication of n matrices M 1 M 2 ...... M n depends on the order in which n - 1 multiplications are performed. Please design a dynamic programming algorithm so that the number of multiplications required to calculate the matrix chain multiplication reaches minimum.

matrix

M 1

M2

M 3

M4 _

M 5

M6 _

dimension

30 × 35

35 × 15

15 × 5

5 × 10

10 × 20

20 × 25



Due to the large number of overlapping sub-problems in the problem, it is not efficient to use the divide and conquer algorithm to recursively arrive at the result, so dynamic programming can be used to solve it. First create a function functionD (the parameter is p array: used to store the number of rows and columns of the matrix, n: the size of the matrix, the two-dimensional array m is used to store the minimum number of times of matrix multiplication in the specified range, and the two-dimensional array s: used to store Specify the optimal break position for the range matrix), first use a for loop to set the number of times of multiplication of a single matrix to zero, and secondly control the size of the matrix by using a for loop to make it increase in size, and set the default break in a scale The point is set to be disconnected at the first matrix, and then the for loop is used to control the movement of the breakpoint, and then the if statement is used to determine whether it is the best breakpoint. When all sizes are looped over, the resulting m[i][n] is the shortest number of multiplications for the entire matrix chain.

#include <iostream>

using namespace std;


 void functionD(int *p,int n,int **m,int **s) {
	for (int i=1 ; i <= n; i++){
		m[i][i]=0;//The number of times of multiplying a single matrix is ​​set to 0
	}
	for(int r=2 ; r <= n; r++) {//r is the size of the matrix chain
		for(int i=1; i<=n-r+1;i++){//i为前边界
			int j=i+r-1;//j is the back boundary
			m[i][j]=m[i][i]+m[i+1][j]+p[i-1]*p[i]*p[j];//Record the breakpoint at i The number of multiplications required at
			s[i][j]=i;//Initialize the breakpoint at i
			for(int k=i+1;k<j;k++){
				int t=m[i][k]/*Utilization of overlapping subproblems*/+m[k+1][j]+p[i-1]*p[k]*p[j];
				if(t<m[i][j]) {//If the number of multiplications of the new breakpoint is less than the original number
					m[i][j]=t;//Update the minimum number of multiplications
					s[i][j]=k;//Save the best breakpoint position
				}
			}
		}
	}
}
int main(){
	int p[] = {30,35,15,5,10,20,25};//Number of rows and columns of the matrix chain
	int n=6;//Number of matrices
	int **m,**s;
	m=new int *[n];
	for(int i=0;i<n;i++){
		m[i]=new int [n];
	}  
	s=new int *[n];
	for(int i=0;i<n;i++){
		s[i]=new int [n];
	}
	 functionD(p,n,m,s) ;
	cout<<"The minimum number of multiplications is"<<m[1][n]<<endl;
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325386517&siteId=291194637