动态规划---矩阵链相乘

问题描述

给定若干个矩阵,寻找最优的相乘次序,使得乘法运算的次数最少,并输出对应的最少运算次数。比如现有三个矩阵ABC,维数分别为A:2×10B:10×2, C:2×10 。虽然(AB)C=A(BC) 结果是相等的,即与相乘次序没有关系。但是(AB)C乘法运算的次数为2×10×2+2×2×10=802×10×2+2×2×10=80,而A(BC)为10×2×10+2×10×10=40010×2×10+2×10×10=400,显然(AB)C的运算次数更少,即效率更高。

思路

求解的关键在于如何将问题分解为若干子问题。我们想象在各个矩阵之间可以放上隔板,那么只要先分别求解左和右的最少乘法次数,再将隔板左右的两部分相乘,就可以得到当前分隔方法的最优解,最后通过比较各种分隔方法,就能得到当前长度的最优解,如下图中四种分隔中我们取最少的次数,即为长度5(5个连续矩阵)的最优解。由于分隔后的长度必定小于当前长度,如此处的子问题长度必定小于5,而子问题已经在之前的迭代过程求得,无需重复计算。通过下一部分的迭代过程展示能有更直观的理解。

思路1:递归,把原数组从i到j-1做切分,计算切分之后两个子序列连乘的乘积之和和两个子序列总体的乘积

时间复杂度指数级,会有重复计算

代码如下:

#递归
def MatrixChainOrder(p,i,j):
    if i == j:
        return 0
    mins = 2 ** 32

    k = i
    while k < j:
        #count分成三份,从k做切分,[i,k]+[k+1,j]+总体
        count = MatrixChainOrder(p,k+1,j) + MatrixChainOrder(p,i,k) + p[i-1] * p[k] * p[j]
        #p[i-1] * p[k] * p[j]是两个子序列连乘的乘积矩阵再相乘的计算量
        print(i,k,j,count)

        if count < mins:
            mins = count
        k += 1
    return mins

思路2:动态规划

自下而上的方式构造临时数组来保存子问题的中间结果,避免重复计算

时间复杂度O(N^3),空间复杂度O(N^2)

迭代过程:

为了更直观的理解,下图和上面是等效的。(符号说明:m[a,b]代表从序号为a到序号为b的矩阵链所需的最少乘法次数,特别地,m[a,a]代表a号矩阵本身,很明显m[a,a]=0。)

先计算第二行(m[1,2],m[2,3],m[3,4],m[4,5]),然后第三行(m[1,3],m[2,4],m[3,5]),....

 

算法实现

arr[]数组用于记录矩阵链信息,其中n号矩阵对应的维数是arr[n-1]*arr[n]。动态规划的核心算法利用3个for循环,最外层控制矩阵链长度,下一层控制起始点,再下一层控制隔板的位置。最后左右合并的时候注意下标的选择,如下图所示。

代码如下:

#动态规划,自下而上
def MatrixChainOrder2(p,n):
    cost = [([None]*n) for i in range(n)]
    i = 1
    while i < n:
        cost[i][i] = 0
        i += 1
    cLen = 2
    #i=start,j=end,cLen=length
    while cLen < n:
        i = 1
        while i < n-cLen+1:
            j = i + cLen - 1
            print(i,j,cLen)
            cost[i][j] = 2 ** 31
            k = i
            while k <= j-1:
                q = cost[i][k] + cost[k+1][j] + p[i-1]*p[k]*p[j]
                if q < cost[i][j]:
                    cost[i][j] = q
                k += 1
            i += 1
        cLen += 1
    # print(cost)
    return cost[1][n-1]

 结果如下:

1 2 2
2 3 2
3 4 2
4 5 2
1 3 3
2 4 3
3 5 3
1 4 4
2 5 4
1 5 5
res 11875

猜你喜欢

转载自www.cnblogs.com/nxf-rabbit75/p/10450009.html