【算法】动态规划 矩阵连乘问题 python

博主根据老师讲义,自己手撸代码,若有错误,多谢指出。 直接上代码

目录

0 讲义

问题

动态规划算法伪代码

举个例子说明

1 代码

迭代实现    输出连乘顺序     主函数


0 讲义

0.1 问题定义

 

0.2 问题分析

0.3 动态规划算法

0.4 伪代码

迭代实现动态规划  code:迭代实现

0.5 举个例子说明

备忘录里的数据在代码里,应该是博主手绘的那个样子。

m[2,4]的意思是,矩阵A2连乘到A4,即A2*A3*A4.

标记函数的输出:code:输出连乘顺序

1 代码

注意,讲义中的矩阵序号从1开始,代码中矩阵序号从0开始。

1.1 code:迭代实现

import numpy as np

"""
对于矩阵{A_0,A_1,... ...,A_n}
对应阶数{P_0,P_1,... ...,P_n,P_n+1}
它们的行列表达为 A_0 = P_0 * P_1
"""
def matrixChain(p, n=1, memo=None, seq=None):
    size = len(p)-n  # 子问题个数
    if n==1:  # 长度为1的矩阵链,数乘次数为0
        memo = np.zeros([size,size], dtype=int)
        seq = np.zeros([size,size], dtype=int)
            
    else:  # 其他长度
        for i in range(size):  # 左边界
            j = i+n-1  # 右边界
            for k in range(i,j):  # 分界位置
                t = memo[i,k] + memo[k+1,j] + p[i]*p[k+1]*p[j+1]
                if t < memo[i,j] or memo[i,j]==0: 
                    memo[i,j] = t
                    seq[i,j] = k
    # 进入n+1
    if n < len(p)-1: 
        matrixChain(p, n+1, memo,seq)
    return memo, seq
"""
memo = 
[[    0 15750  7875  9375 11875]
 [    0     0  2625  4375  7125]
 [    0     0     0   750  2500]
 [    0     0     0     0  1000]
 [    0     0     0     0     0]]

seq = 
[[0 0 0 2 2]
 [0 0 1 2 2]
 [0 0 0 2 2]
 [0 0 0 0 3]
 [0 0 0 0 0]]
"""

1.2 code:输出连乘顺序

def prtSeq(seq, i, j):
    size = j-i+1
    if size ==1:
        return 'A%d'%i
    else:   # 至少有三个元素,才要考虑数乘顺序
        k = seq[i,j]  # 分界位置
        res = ''
        res += '('+ prtSeq(seq, i,   k)
        res += prtSeq(seq, k+1, j) + ')'
        return res

"""
res = ((A0(A1A2))(A3A4))
注意,输出结果会比正确结果多一对()
"""

1.3 code:主函数

n = eval(input('请输入矩阵个数:'))
p = eval(input('请输入矩阵尺寸:'))
m,seq = matrixChain(p)
res = prtSeq(seq,0,n-1)
print('最佳数乘次序:%s, 此时数乘次数:%d'%(res[1:-1], m[0,-1]))

"""
请输入矩阵个数:5
请输入矩阵尺寸:30,35,15,5,10,20
最佳数乘次序:(A0(A1A2))(A3A4), 此时数乘次数:11875
"""

 

  • 10
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值