Learning "Introduction to Algorithms" (18) - matrix chain multiplication of dynamic programming (C language)


foreword

This article mainly explains the matrix chain multiplication problem in dynamic programming: given a matrix chain, get its minimum cost calculation order. The analysis of the dynamic programming scheme is given, and the C language implementation is given.


1. Matrix chain multiplication

1. Problem description

Given a sequence (chain of matrices) of n matrices < A 1 , A 2 , A 3 , A 4 , . . . , A n > <A_1,A_2,A_3,A_4,...,A_n><A1,A2,A3,A4,...,An> , now we wish to compute its product
A 1 A 2 A 3 A 4 . . . A n A_1 A_2A_3A_4...A_nA1A2A3A4...An
For matrix chain multiplication, we can determine which two matrices to multiply first by adding parentheses. Regardless of the order of multiplication, it does not affect the result in the end.
However, for matrix multiplication between different orders, the computer has to pay a completely different price.
For example < A 1 , A 2 , A 3 > , where A 1 is 2 ∗ 3; A 2 is 3 ∗ 4; A 3 is 4 ∗ 1 <A_1,A_2,A_3>, where A_1 is 2*3; A_2 is 3*4; A_3 is 4*1<A1,A2,A3>,where A1for 23A2for 34A3for 41
We can calculate the cutting cost of two different strategies:

  • ( ( A 1 A 2 ) A 3 ) = 2 ∗ 3 ∗ 4 + 2 ∗ 4 ∗ 1 = 32 ((A_1A_2)A_3)=2*3*4+2*4*1=32 ((A1A2)A3)=234+241=32
  • ( A 1 ( A 2 A 3 ) ) = 3 ∗ 4 ∗ 1 + 2 ∗ 3 ∗ 1 = 18 (A_1(A_2A_3))=3*4*1+2*3*1=18 (A1(A2A3))=341+231=18

Obviously, the two costs are completely different. Now our problem isGiven a matrix chain, get its minimum cost calculation order

2. Problem solving

1. Optimal sub-problem structure

We first give the corresponding recursive solution formula directly:
w [ i , j ] = { 0 if i = jmin { w [ i , k ] + w [ k + 1 , j ] + pi − 1 pkpj } if i < jw [i,j]=\begin{cases} 0& \text{ if }i=j \\ min\{ w[i,k]+w[k+1,j]+p_{i-1}p_kp_j\} & \text{ if } i<j \\ \end{cases}w[i,j]={ 0min{ w[i,k]+w[k+1,j]+pi1pkpj} if i=j if i<j

  • w[i,j] represents the minimum cost of the matrix chain on the path from the i-th matrix to the j-th matrix
  • p i − 1 p k p j p_{i-1}p_kp_j pi1pkpjRepresents the cost required to construct from an optimal sub-solution to its optimal parent solution

2. Dynamic programming

We use a two-dimensional array to record the optimal solution to the subproblem. For example, the optimal solution of w[2,4] is recorded in the array w[1,3] (because the array starts from 0).
At the same time, we start to find the optimal solution from the sub-matrix chain with a length of 2, and then increase the length by 1 until we finally get the optimal solution of the n-matrix chain.
This process uses a three-layer cycle

  • The first layer of loop traverses the length of the matrix chain from small to large
  • The second layer loops through the first layer loop to determine the position of the first matrix in the sub-matrix chain under the length
  • The third layer loops through all the "cutting" schemes of the matrix chain determined by the first two loops

3. Optimal solution construction

After the three-layer loop of dynamic programming, we can now get the specific value of the minimum cost, but what is the specific order of matrix multiplication, we need to construct the optimal solution.
We use a two-dimensional number s group to assist us in constructing the optimal solution.

  • We use s[0,6] to record the first parenthesized position of the matrix chain w[1,7], that is, its k value.
  • We record the optimal value of k for the chain of matrices for all cases.
  • Then by calling the algorithm recursively, the parenthesized output results can be obtained. For details, see the code below. Readers can also quickly determine the solution by drawing a recursive tree.

Three, C code

1. Code

#include<stdio.h>
#include<stdlib.h>
#include<time.h>



//由于有n个矩阵链乘
//需要n+1个存储单元来存储行列信息
//此处SIZE为存储单元的个数
//因此矩阵链乘的个数是SIZE-1 
#define SIZE 10
//此处可以规定矩阵的行列数为1~LIM的随机数 
#define LIM 100
//注意:
//由于计算机存储数大小的限制
//SIZE和LIM不宜过大
//过大肯定会使得程序崩溃 



int Matrix_chain_order(int *p,int s[][SIZE-1],int w[][SIZE-1],int size)
{
    
    
	int i=0;
	int j=0;
	int k=0;
	int q=0;
	int l=0;
	int r=0;
	for(i=0;i<size-1;i++)
	{
    
    
		w[i][i]=0;
		s[i][i]=0;
	}
	for(i=2;i<=(size-1);i++)
	{
    
    
		for(j=1;j<=(size-i);j++)
		{
    
    
			l=j;
			r=j+i-1;
			w[l-1][r-1]=10000000;
			for(k=l;k<r;k++)
			{
    
    
				q=w[l-1][k-1]+w[k][r-1]+p[l-1]*p[k]*p[r];
				if(q<w[l-1][r-1])
				{
    
    
					w[l-1][r-1]=q;
					s[l-1][r-1]=k;
				}
			}
		}
	}
	return w[0][size-2];
}



void print_priority(int s[][SIZE-1],int l,int r)
{
    
    
	if(l==r)
	{
    
    
		printf("A%d",l+1);
		return;
	}
	printf("(");
	print_priority(s,l,s[l][r]-1);
	print_priority(s,s[l][r],r);
	printf(")");		
}



int main()
{
    
    
	int p[SIZE];
	int s[SIZE-1][SIZE-1];
	int w[SIZE-1][SIZE-1];
	int min_pay;
	int i=0;
	int j=0;
	srand((unsigned)time(NULL));
	for(i=0;i<SIZE;i++)
	{
    
    
		p[i]=rand()%LIM+1;
	}
	for(i=0;i<SIZE;i++)
	{
    
    
		printf("%5d",p[i]);
	}
	printf("\n");
	min_pay=Matrix_chain_order(p,s,w,SIZE);
	printf("%5d\n",min_pay);
	print_priority(s,0,SIZE-2);
	return 0;
} 

2. Results

insert image description here


Summarize

Readers are welcome to correct me if there is any inappropriateness in the article.
For other questions about dynamic programming, you can also refer to:
"Introduction to Algorithms" Learning (17)----Dynamic Programming Steel Strip Cutting (C Language)

Guess you like

Origin blog.csdn.net/weixin_52042488/article/details/127147710