Matrix multiplication idea

[problem description]

Given n matrices {A1,A2,..., An}, where Ai and Ai+1 are multiplicative, i=1, 2,..., n-1. How to determine the calculation order of matrix continued product so that the number of times required to calculate matrix continued product according to this order is the least. For example, given that the dimensions of three consecutive multiplication matrices {A1,A2, A3} are 101001005 and 550 respectively, using (A1A2)A3, the number of multiplication is 101005 + 10550 = 7500 times, while using A1 (A2A3), the number of multiplication is 100550 + 10100 * 50 = 75000 times. Obviously, the best order is (A1A2)A3, and the number of multiplication is 7500 times.

analysis:

Matrix chain multiplication problem description:
Given the sequence {A1, A2,..., an} composed of n matrices, for the product A1A2... An, find the bracketed method to minimize the number of multiplications.

1) Finding the optimal substructure

The most difficult part of this problem is to find the optimal substructure. Any bracketed method for the product A1A2... An will divide the sequence into two parts somewhere, that is, where the last multiplication is calculated. We record this position as k, that is, first calculate A1...Ak and Ak+1...An, and then multiply the results of these two parts.
The optimal substructure is as follows: assuming that an optimal bracketing of A1A2... An separates the product between Ak and Ak+1, the bracketing method of prefix sub chain A1... Ak must be an optimal bracketing of A1... An, and the suffix sub chain is the same.

We don't know the exact position of k at first. We need to traverse all the positions to ensure that we can find the appropriate k to divide the product.

2) Construct recursive solution

• m[i][j] represents the calculation amount of A[i:j];
• The calculation amount of A[i:k] is m[i][k];
• The calculation amount of a [K + 1: J] is m[k+1][j]

Therefore, m[i][j] = m[i][k] + m[k+1][j] + p[i-1] * p[i] * p[j];

Because i and j are subscripts of the matrix, they are greater than 0. For example, the matrix is a1-a6, i = 1, j = 6
Where p is the number of rows and columns of each matrix, as shown in the figure below

(p[i-1] * p[i] * p[j]: calculation amount of the last two matrices)
At this time, i=1 and j=6
Assuming that the position of k (the position of brackets) is p3 at this time, the calculation amount is min (m[1][3]+m[4][6]+p[0]p[3]p[6])

Calculation order

Matrix A1-A6, it can be seen that the range of k is between p1-p5
i=1, j=6, n=6, so the range of K is I < = k < J-1

```#include<iostream>
using namespace std;

const int N=7;
//p is the matrix chain, p[0],p[1] represents the number of rows and columns of the first matrix, p[1],p[2] represents the number of rows and columns of the second matrix... Length is the length of p
//Therefore, if there are six matrices, length=7, m is the two-dimensional matrix for storing the optimal result, and s is the matrix for storing the route for selecting the optimal result
//Two dimensional matrix
void MatrixChainOrder(int *p,int m[N][N],int s[N][N],int length)
{
int n=length-1;
int l,i,j,k,q=0;
//m[i][i] has only one matrix, so the multiplication number is 0, that is, m[i][i]=0;
for(i=1;i<length;i++)
{
m[i][i]=0;
}
//l represents the length of the matrix chain
// When l=2, calculate m[i,i+1],i=1,2,...,n-1 (minimum cost of chain with length l=2)
//    Even if m[i,i+l-1] cost (for example, length 4 is A2-A5, so j=i+l-1), so i + (l-1) < = n
for(l=2;l<=n;l++)
{
for(i=1;i<=n-l+1;i++)
{
j=i+l-1; //Take i as the starting position and j as the end of the chain with length l,
m[i][j]=0x7fffffff;
//Hexadecimal max, initialization. If this value is not overwritten, it means that the final result will not go through it
//k from i to j-1, divided by k, in this question, the range of k is p1-p5
for(k=i;k<=j-1;k++)
{
q=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(q<m[i][j])//If it is less than this value, it is overwritten
{
m[i][j]=q;
s[i][j]=k;//Where to save k
}
}
}
}
cout << m[1][N-1] << endl;//The best result is placed in the last array
}
{
if(i==j)
{
cout<<"A"<<i;
}
else
{
cout<<"(";
cout<<")";
}
}
int main()
{
int p[N]={30,35,15,5,10,20,25};
int m[N][N],s[N][N];
MatrixChainOrder(p,m,s,N);