dynamic programming_矩阵链乘法(matrix_chain_order)_python

theory

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
记住,矩阵子链 A i ⋯ A k A_{i}\cdots A_{k} AiAk链内各个矩阵相乘的结果矩阵的规模可以仅从该子链的第一个矩阵 A i A_{i} Ai的行数 p i − 1 p_{i-1} pi1和最后一个矩阵 A k A_{k} Ak的列数 p k p_{k} pk有关
即,结果矩阵的规模为 p i − 1 × p k p_{i-1}\times p_{k} pi1×pk
这是理解 m [ 2 , 2 ] + m [ 3 , 5 ] + p 1 p 2 p 5 m[2,2]+m[3,5]+p_{1}p_{2}p_{5} m[2,2]+m[3,5]+p1p2p5中为什么是 + p 1 p 2 p 5 +p_{1}p_{2}p_{5} +p1p2p5的基础
p i 为 第 i 个 矩 阵 的 列 数 ( i > = 1 ) , 至 于 行 数 , 则 为 p i − 1 p_{i}为第i个矩阵的列数(i>=1),至于行数,则为p_{i-1} pii(i>=1),,pi1
m[2,2]相当于单个矩阵构成的矩阵链(k=i=2),行数为 p 2 − 1 = p 1 ( i = 2 ) p_{2-1}=p_{1}(i=2) p21=p1(i=2),列数为 p 2 ( k = i = 2 ) p_{2}(k=i=2) p2(k=i=2),则,规格为 p 1 × p 2 p_{1}\times p_{2} p1×p2

specific examples:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Construct the optimal solution

the parentheses solution:
在这里插入图片描述

python:

import math
def matrix_chain_order(list_p):
    """[summary]

    Args:
        list_p ([type]): [description]

    Returns:
        [type]: [description]
    """
    n = len(list_p)-1
    ''' we could think that the table_min_costs contains the optimal cost values of the different subproblem(sub_matrix chain) scales
    (from bottom to top to solve the problem)
    '''
    # the table to save the lowest costs to multiple the matrix chain
    table_min_costs = [[0 for i in range(0, n+1)]
                       for j in range(0, n+1)]  # (n+1)*(n+1)
    # the table_save_partition save the the optimal partition point:make the multiplication cost lowest each scale cases
    table_save_partition = [
        [0 for i in range(0, n+1)] for j in range(0, n+1)]  # (n)*(n)
    ''' the length of the sub_matrix chain is 1 cases could be centralized process:assign them as 0 in the table_min_costs '''
    for i in range(1, n+1):
        table_min_costs[i][i] = 0
    ''' the essential part of the algorithm: '''
    # length is the chain length(traverse the all kinds of sub matrix chains cases(length>1))
    for length in range(2, n+1):
        ''' each specific length cases have different partition schemes: 
        traverse all these divide cases:'''
        for start_i in range(1, n-length+2):  # the start_i is the index of each sub_matrix chain
            # make the j-i+1==l(namely ,the length of sub_matrix chain)
            end_i = start_i+length-1
            # initial the costs as infinite value:
            table_min_costs[start_i][end_i] = math.inf
            """ 
            # focus on the each sepecified sub_matrix chain
            # the following loop will test(run) j-i times:to find the optimal split point:
            # the index to_opt_partition is the index of the optimal split point(the matrix to_opt_partition matrix will be belong to the former subproble(sub_matrix chain)) 
            """
            for to_opt_partition in range(start_i, end_i):
                ''' the to_opt_partition >=start_i>=1 '''
                to_lowest_cost = table_min_costs[start_i][to_opt_partition] + table_min_costs[to_opt_partition+1][end_i] + \
                    list_p[start_i-1]*list_p[to_opt_partition]*list_p[end_i]
                if to_lowest_cost < table_min_costs[start_i][end_i]:
                    table_min_costs[start_i][end_i] = to_lowest_cost

                    table_save_partition[start_i][end_i] = to_opt_partition

    return table_min_costs, table_save_partition


def print_optimal_parentheses(s, i, j):
    """
    matrix_index=1
    Args:
        s ([list]): [table_save_partition(optimal)]
        i ([int]): [start_i index of the subproblem]
        j ([int]): [end_i index of the subproblem]
    """
    """ the simplest case (the sub_matrix chain length is 1)
    the case as the recursive exit:"""
    if i == j:
        print("A"+str(i), end="")
    else:
        print("(", end="")
        print_optimal_parentheses(s, i, s[i][j])
        print_optimal_parentheses(s, s[i][j]+1, j)
        print(")", end="")


def test(list_p):
    table_min_costs, table_save_partition = matrix_chain_order(list_p)
    print_optimal_parentheses(table_save_partition, 1, len(list_p)-1)


list_p = [30, 35, 15, 5, 10, 20, 25]


test(list_p)
              
                    
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值