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]
矩阵链乘法问题
猜你喜欢
转载自blog.csdn.net/weixin_49346755/article/details/121485448
今日推荐
周排行