📜  矩阵链乘法(AO(N^2) 解)

📅  最后修改于: 2021-09-17 16:01:02             🧑  作者: Mango

给定一个矩阵序列,找到将这些矩阵相乘的最有效方法。问题实际上不是执行乘法,而只是决定执行乘法的顺序。
我们有很多选择来乘以矩阵链,因为矩阵乘法是关联的。换句话说,无论我们如何将乘积括起来,结果都是一样的。例如,如果我们有四个矩阵 A、B、C 和 D,我们将有:

(ABC)D = (AB)(CD) = A(BCD) = ....

但是,我们将乘积括起来的顺序会影响计算乘积或效率所需的简单算术运算的数量。例如,假设 A 是一个 10 × 30 的矩阵,B 是一个 30 × 5 的矩阵,而 C 是一个 5 × 60 的矩阵。然后,

(AB)C = (10×30×5) + (10×5×60) = 1500 + 3000 = 4500 operations
    A(BC) = (30×5×60) + (10×30×60) = 9000 + 18000 = 27000 operations.

显然,第一个括号需要较少的操作。
给定一个数组 p[],它表示矩阵链,使得第 i 个矩阵 Ai 的维度为 p[i-1] xp[i]。我们需要编写一个函数MatrixChainOrder(),它应该返回乘法链所需的最小乘法次数。

Input: p[] = {40, 20, 30, 10, 30}   
  Output: 26000  
  There are 4 matrices of dimensions 40x20, 20x30, 30x10 and 10x30.
  Let the input 4 matrices be A, B, C and D.  The minimum number of 
  multiplications are obtained by putting parenthesis in following way
  (A(BC))D --> 20*30*10 + 40*20*10 + 40*10*30

  Input: p[] = {10, 20, 30, 40, 30} 
  Output: 30000 
  There are 4 matrices of dimensions 10x20, 20x30, 30x40 and 40x30. 
  Let the input 4 matrices be A, B, C and D.  The minimum number of 
  multiplications are obtained by putting parenthesis in following way
  ((AB)C)D --> 10*20*30 + 10*30*40 + 10*40*30

  Input: p[] = {10, 20, 30}  
  Output: 6000  
  There are only two matrices of dimensions 10x20 and 20x30. So there 
  is only one way to multiply the matrices, cost of which is 10*20*30

我们已经讨论了矩阵链乘法问题的 O(n^3) 解决方案。
注意:以下解决方案不适用于许多情况。例如:对于输入 {2, 40, 2, 40, 5},正确答案是 580 但此方法返回 720
还有另一种类似的方法可以解决这个问题。更直观和递归的方法。

C++
// CPP program to implement optimized matrix chain multiplication problem.
#include
using namespace std;
 
// Matrix Mi 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
    dp[][]. 0th row and 0th column of dp[][] are not used */
    int dp[n][n];
 
    /* dp[i, j] = Minimum number of scalar multiplications needed to compute the matrix M[i]M[i+1]...M[j]
                = M[i..j] where dimension of M[i] is p[i-1] x p[i] */
                 
    // cost is zero when multiplying one matrix.
    for (int i=1; i


Java
// Java program to implement optimized matrix chain multiplication problem.
import java.util.*;
import java.lang.*;
import java.io.*;
 
 
class GFG{
// Matrix Mi has dimension p[i-1] x p[i] for i = 1..n
static int MatrixChainOrder(int p[], int n)
{
 
    /* For simplicity of the program, one extra row and one extra column are
     allocated in dp[][]. 0th row and 0th column of dp[][] are not used */
    int [][]dp=new int[n][n];
 
    /* dp[i, j] = Minimum number of scalar multiplications needed to compute the matrix M[i]M[i+1]...M[j]
                = M[i..j] where dimension of M[i] is p[i-1] x p[i] */
                 
    // cost is zero when multiplying one matrix.
    for (int i=1; i


Python3
# Python3 program to implement optimized
# matrix chain multiplication problem.
 
# Matrix Mi has dimension
# p[i-1] x p[i] for i = 1..n
def MatrixChainOrder(p, n):
     
    # For simplicity of the program, one
    # extra row and one extra column are
    # allocated in dp[][]. 0th row and
    # 0th column of dp[][] are not used
    dp = [[0 for i in range(n)]
             for i in range(n)]
 
    # dp[i, j] = Minimum number of scalar
    # multiplications needed to compute
    # the matrix M[i]M[i+1]...M[j] = M[i..j]
    # where dimension of M[i] is p[i-1] x p[i]
                 
    # cost is zero when multiplying one matrix.
    for i in range(1, n):
        dp[i][i] = 0
 
    # Simply following above recursive formula.
    for L in range(1, n - 1):
        for i in range(n - L):
            dp[i][i + L] = min(dp[i + 1][i + L] +
                                p[i - 1] * p[i] * p[i + L],
                               dp[i][i + L - 1] +
                                p[i - 1] * p[i + L - 1] * p[i + L])
     
    return dp[1][n - 1]
 
# Driver code
arr = [10, 20, 30, 40, 30]
size = len(arr)
print("Minimum number of multiplications is",
                 MatrixChainOrder(arr, size))
 
# This code is contributed
# by sahishelangia


C#
// C# program to implement optimized
// matrix chain multiplication problem.
using System;
 
class GFG
{
// Matrix Mi has dimension
// p[i-1] x p[i] for i = 1..n
static int MatrixChainOrder(int []p, int n)
{
 
    /* For simplicity of the program,
       one extra row and one extra
       column are allocated in dp[][].
       0th row and 0th column of dp[][]
       are not used */
    int [,]dp = new int[n, n];
 
    /* dp[i, j] = Minimum number of scalar
       multiplications needed to compute
       the matrix M[i]M[i+1]...M[j] = M[i..j]
       where dimension of M[i] is p[i-1] x p[i] */
                 
    // cost is zero when multiplying
    // one matrix.
    for (int i = 1; i < n; i++)
        dp[i, i] = 0;
 
    // Simply following above
    // recursive formula.
    for (int L = 1; L < n - 1; L++)
    for (int i = 1; i < n - L; i++)    
        dp[i, i + L] = Math.Min(dp[i + 1, i + L] +
                                 p[i - 1] * p[i] * p[i + L],
                                dp[i, i + L - 1] + p[i - 1] *
                                 p[i + L - 1] * p[i + L]);
     
    return dp[1, n - 1];
}
 
// Driver code
public static void Main()
{
    int []arr = {10, 20, 30, 40, 30} ;
    int size = arr.Length;
 
    Console.WriteLine("Minimum number of multiplications is " +
                                  MatrixChainOrder(arr, size));
}
}
 
// This code is contributed by anuj_67


PHP


Javascript


输出:
Minimum number of multiplications is 30000

感谢 Rishi_Lazy 提供以上优化的解决方案。
时间复杂度: O(n 2 )
在矩阵链乘法中打印括号

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程