矩阵链乘法问题

import numpy as np
# 矩阵链乘法问题
# 问题描述:
# 给定一个n个矩阵的序列(矩阵链)<a1,a2,...,an>,矩阵ai的规模为pi-1×pi
# 求矩阵链的完全括号化方案,使得矩阵乘积a1a2...an所需标量乘积最少
# 假设矩阵a的规模为p×q,矩阵b的规模为q×r,那么矩阵a和矩阵b相乘所需的标量乘法为p×q×r

# 动态规划法
# 算法思想:
# 有j-i+1个矩阵相乘aiai+1...akak+1...aj-1aj,假设最优括号化匹配方案在akak+1之间划分
# 则整个矩阵链的最低代价c(i,j)为三部分相加:
# 前半部分aiai+1...ak(连乘后的规模为pi-1×pk)的最低代价c(i,k)
# 后半部分ak+1...aj-1aj(连乘后的规模为pk×pj)的最低代价c(k+1,j)
# 前半部分相乘后的矩阵和后半部分相乘后的矩阵相乘的代价pi-1×pk×pj
# 由于分割点ak不确定,因此最小代价为遍历意义下的最小代价
# 即c(i, j) = min{c(i, k) + c(k+1, j) + pi-1pkpj},i<=k<j,其中c(i, j) = 0,i=j
def matrix_chain_multiply(p):
    # 假设矩阵规模a1(m×n) a2(n×r) a3(r×s)
    # 用一维数组存储为p = [m, n, r, s]
    # 则a1的规模可以表示为p[0]*p[1]
    n = len(p) - 1
    c = np.zeros((n + 1, n + 1))
    for d in range(2, n + 1):
        # 求c[i][j]的代价,存储在二维矩阵c中,第0行和第0列不使用,
        # c[1][2]表示矩阵链a1a2的最小代价,c[1][5]表示矩阵链a1a2a3a4a5的最小代价
        for i in range(1, n):
            j = i + d - 1
            # j的最大值应为n,如果j大于n,则越界,退出当前循环
            if j > n:
                break
            c[i][j] = float("inf")
            # 遍历求解c[i][j]
            for k in range(i, j):
                c[i][j] = min(c[i][k] + c[k+1][j] + p[i-1]*p[k]*p[j], c[i][j])
    # 返回矩阵链a1a2...an的最小代价c[1][n]
    return c[1][n]

Guess you like

Origin blog.csdn.net/weixin_49346755/article/details/121485448
Recommended