C Program for Matrix Chain Multiplication | DP-8
Last Updated :
09 Nov, 2023
Write a C program for a given dimension of a sequence of matrices in an array arr[], where the dimension of the ith matrix is (arr[i-1] * arr[i]), the task is to find the most efficient way to multiply these matrices together such that the total number of element multiplications is minimum.
Examples:
Input: arr[] = {40, 20, 30, 10, 30}
Output: 26000
Explanation: There are 4 matrices of dimensions 40×20, 20×30, 30×10, 10×30.
Let the input 4 matrices be A, B, C, is, and D.
The minimum number of multiplications is obtained by putting parenthesis in the following way (A(BC))D.
The minimum is 20*30*10 + 40*20*10 + 40*10*30
Input: arr[] = {1, 2, 3, 4, 3}
Output: 30
Explanation: There are 4 matrices of dimensions 1×2, 2×3, 3×4, 4×3.
Let the input 4 matrices be A, B, C, and D.
The minimum number of multiplications is obtained by putting parenthesis in the following way ((AB)C)D.
The minimum number is 1*2*3 + 1*3*4 + 1*4*3 = 30
Input: arr[] = {10, 20, 30}
Output: 6000
Explanation: There are only two matrices of dimensions 10×20 and 20×30.
So there is only one way to multiply the matrices, cost of which is 10*20*30
C Program for Matrix Chain Multiplication using Recursion:
Two matrices of size m*n and n*p when multiplied, they generate a matrix of size m*p and the number of multiplications performed are m*n*p.
Now, for a given chain of N matrices, the first partition can be done in N-1 ways. For example, sequence of matrices A, B, C and D can be grouped as (A)(BCD), (AB)(CD) or (ABC)(D) in these 3 ways.
So a range [i, j] can be broken into two groups like {[i, i+1], [i+1, j]}, {[i, i+2], [i+2, j]}, . . . , {[i, j-1], [j-1, j]}.
- Each of the groups can be further partitioned into smaller groups and we can find the total required multiplications by solving for each of the groups.
- The minimum number of multiplications among all the first partitions is the required answer.
Step-by-step approach:
- Create a recursive function that takes i and j as parameters that determines the range of a group.
- Iterate from k = i to j to partition the given range into two groups.
- Call the recursive function for these groups.
- Return the minimum value among all the partitions as the required minimum number of multiplications to multiply all the matrices of this group.
- The minimum value returned for the range 0 to N-1 is the required answer.
Below is the implementation of the above approach.
C
// C code to implement the
// matrix chain multiplication using recursion
#include <limits.h>
#include <stdio.h>
// Matrix Ai has dimension p[i-1] x p[i]
// for i = 1 . . . n
int MatrixChainOrder(int p[], int i, int j)
{
if (i == j)
return 0;
int k;
int min = INT_MAX;
int count;
// Place parenthesis at different places
// between first and last matrix,
// recursively calculate count of multiplications
// for each parenthesis placement
// and return the minimum count
for (k = i; k < j; k++)
{
count = MatrixChainOrder(p, i, k)
+ MatrixChainOrder(p, k + 1, j)
+ p[i - 1] * p[k] * p[j];
if (count < min)
min = count;
}
// Return minimum count
return min;
}
// Driver code
int main()
{
int arr[] = { 1, 2, 3, 4, 3 };
int N = sizeof(arr) / sizeof(arr[0]);
// Function call
printf("Minimum number of multiplications is %d ",
MatrixChainOrder(arr, 1, N - 1));
getchar();
return 0;
}
OutputMinimum number of multiplications is 30
The time complexity of the solution is exponential
Auxiliary Space: O(1)
C Program for Matrix Chain Multiplication using Dynamic Programming (Memoization):
Step-by-step approach:
- Build a matrix dp[][] of size N*N for memoization purposes.
- Use the same recursive call as done in the above approach:
- When we find a range (i, j) for which the value is already calculated, return the minimum value for that range (i.e., dp[i][j]).
- Otherwise, perform the recursive calls as mentioned earlier.
- The value stored at dp[0][N-1] is the required answer.
Below is the implementation of the above approach:
C
#include <stdio.h>
#include <limits.h>
int dp[100][100];
// Function for matrix chain multiplication
int matrixChainMemoised(int p[], int i, int j) {
if (i == j) {
return 0;
}
if (dp[i][j] != -1) {
return dp[i][j];
}
dp[i][j] = INT_MAX;
for (int k = i; k < j; k++) {
dp[i][j] = (dp[i][j] < (matrixChainMemoised(p, i, k)
+ matrixChainMemoised(p, k + 1, j)
+ p[i - 1] * p[k] * p[j])) ? dp[i][j] : (matrixChainMemoised(p, i, k)
+ matrixChainMemoised(p, k + 1, j)
+ p[i - 1] * p[k] * p[j]);
}
return dp[i][j];
}
int MatrixChainOrder(int p[], int n) {
int i = 1, j = n - 1;
return matrixChainMemoised(p, i, j);
}
int main() {
int arr[] = {1, 2, 3, 4};
int n = sizeof(arr) / sizeof(arr[0]); // Corrected this line
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
dp[i][j] = -1;
}
}
printf("Minimum number of multiplications is %d\n", MatrixChainOrder(arr, n));
return 0;
}
OutputMinimum number of multiplications is 18
Time Complexity: O(N3 )
Auxiliary Space: O(N2) ignoring recursion stack space
C Program for Matrix Chain Multiplication using Dynamic Programming (Tabulation):
In iterative approach, we initially need to find the number of multiplications required to multiply two adjacent matrices. We can use these values to find the minimum multiplication required for matrices in a range of length 3 and further use those values for ranges with higher lengths.
Build on the answer in this manner till the range becomes [0, N-1].
Step-by-step approach:
- Iterate from l = 2 to N-1 which denotes the length of the range:
- Iterate from i = 0 to N-1:
- Find the right end of the range (j) having l matrices.
- Iterate from k = i+1 to j which denotes the point of partition.
- Multiply the matrices in range (i, k) and (k, j).
- This will create two matrices with dimensions arr[i-1]*arr[k] and arr[k]*arr[j].
- The number of multiplications to be performed to multiply these two matrices (say X) are arr[i-1]*arr[k]*arr[j].
- The total number of multiplications is dp[i][k]+ dp[k+1][j] + X.
- The value stored at dp[1][N-1] is the required answer.
Below is the implementation of the above approach:
C
// See the Cormen book for details of the following
// algorithm
#include <limits.h>
#include <stdio.h>
// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
int MatrixChainOrder(int p[], int n)
{
/* For simplicity of the program,
one extra row and one
extra column are allocated in m[][].
0th row and 0th
column of m[][] are not used */
int m[n][n];
int i, j, k, L, q;
/* m[i, j] = Minimum number of
scalar multiplications
needed to compute the matrix
A[i]A[i+1]...A[j] =
A[i..j] where dimension of A[i]
is p[i-1] x p[i] */
// cost is zero when multiplying one matrix.
for (i = 1; i < n; i++)
m[i][i] = 0;
// L is chain length.
for (L = 2; L < n; L++) {
for (i = 1; i < n - L + 1; i++)
{
j = i + L - 1;
m[i][j] = INT_MAX;
for (k = i; k <= j - 1; k++)
{
// q = cost/scalar multiplications
q = m[i][k] + m[k + 1][j]
+ p[i - 1] * p[k] * p[j];
if (q < m[i][j])
m[i][j] = q;
}
}
}
return m[1][n - 1];
}
// Driver code
int main()
{
int arr[] = { 1, 2, 3, 4 };
int size = sizeof(arr) / sizeof(arr[0]);
printf("Minimum number of multiplications is %d ",
MatrixChainOrder(arr, size));
getchar();
return 0;
}
OutputMinimum number of multiplications is 18
Time Complexity: O(N3 )
Auxiliary Space: O(N2)
Please refer complete article on Matrix Chain Multiplication | DP-8 for more details!
Similar Reads
Graph Representation using Adjacency Matrix in C A graph is a data structure having a set of vertices and a collection of edges that each connect a pair of vertices. There are several ways to represent a graph in computer memory, and one of them is using an adjacency matrix. An adjacency matrix is a 2D array with one row per vertex and one column
4 min read
Matrix Multiplication in C A matrix is a collection of numbers organized in rows and columns, represented by a two-dimensional array in C. Matrices can either be square or rectangular. In this article, we will learn the multiplication of two matrices in the C programming language. ExampleInput: mat1[][] = {{1, 2}, {3, 4}} mat
3 min read
C Program for Identity Matrix Introduction to Identity Matrix : The dictionary definition of an Identity Matrix is a square matrix in which all the elements of the principal or main diagonal are 1's and all other elements are zeros. In the below image, every matrix is an Identity Matrix. In linear algebra, this is sometimes call
2 min read
C Program to Find Determinant of a Matrix What is the Determinant of a Matrix? The determinant of a Matrix is a special number that is defined only for square matrices (matrices that have the same number of rows and columns). A determinant is used at many places in calculus and other matrices related to algebra, it actually represents the m
6 min read
C Program for Kronecker Product of two matrices Given a {m} imes{n} matrix A and a {p} imes{q} matrix B, their Kronecker product C = A tensor B, also called their matrix direct product, is an {(mp)} imes{(nq)} matrix. A tensor B = |a11B a12B| |a21B a22B| = |a11b11 a11b12 a12b11 a12b12| |a11b21 a11b22 a12b21 a12b22| |a11b31 a11b32 a12b31 a12b32| |
3 min read
Add Matrix in C Matrices are the collection of numbers arranged in order of rows and columns. In this article, we will learn to write a C program for the addition of two matrices.The idea is to use two nested loops to iterate over each element of the matrices. The addition operation is performed by adding the corre
4 min read