动态规划算法——矩阵链相乘

一、递归实现

  伪代码描述:

  RecurMatrixChain(P,i,j)

输入:矩阵链Ai..j的输入为向量P=<Pi-1,Pi,···,Pj>,其中1≤i≤j≤n

输出:计算Ai..j的所需最小乘法运算次数m[i,j]和最后一次运算的位置s[i][j]

 1 if i=j
 2 then m[i,j]←0; s[i,j]←i; return m[i,j]
 3 m[i,j]←∞
 4 s[i,j]←i
 5 for k←i to j-1 do    //考虑所有可能的划分位置
 6     q←RecurMatrixChain(P,i,k)+RecurMatrixChain(P,k+1,j)+Pi-1PkPj
 7     if q<m[i,j]
 8     then m[i,j]←q    //用找到的更好优化函数值替换原值,并记录划分位置
 9         s[i,j]←k
10 return m[i,j]

指数级别复杂度:T(n) ≥ 2n-1

  Python代码实现:

import sys

P = [30,35,15,25,10,20]
m = [[0]*6 for i in range(6)]
s = [[0]*6 for i in range(6)]

def recurMatrixChain(P,i,j):
    if i==j:
        m[i][j]=0
        s[i][j]=i
        return m[i][j]
    m[i][j]=sys.maxint  #无穷大
    s[i][j]=i
    for k in range(i,j):
        q=recurMatrixChain(P,i,k)+recurMatrixChain(P,k+1,j)+P[i-1]*P[k]*P[j]
        if q<m[i][j]:
            m[i][j]=q
            s[i][j]=k
    return m[i][j]
        

mm = recurMatrixChain(P,1,5)
print mm

 

二、迭代实现

  伪代码描述:

  MatrixChain(P,n)

输入:矩阵链A1..n的输入为向量P=<P0,P1,...,Pn>

输出:计算Ai..j的所需最小乘法运算此时m[i,j]和最后一次运算的位置s[i,j],1≤i≤j≤n

 

 1 令所有的m[i,j]初值为0,s[i,j]初值为i,1≤i≤j≤n
 2 for r←2 to n do    //r为当前计算的链长(子问题规模)
 3     for i←1 to n-r+1 do    //n-r+1为最后一个r链的前边界
 4         j←i+r-1     //计算前边界为i,长为r链的后边界j
 5         m[i,j]←m[i+1,j]+Pi-1*Pi*Pj  //划分为Ai(Ai+1···Aj),*为普通乘法
 6         s[i][j]←i  //记录分割位置
 7         for k←i+1 to j-1 do
 8             t←m[i,k]+m[k+1,j]+Pi-1*Pk*Pj  //划分位置是(Ai···Ak)(Ak+1···Aj)
 9             if t<m[i,j]    //用更好的值替换
10             then m[i,j]←t
11                     s[i,j]←k

 

   指数级别复杂度:W(n) = O(n3)

    Python代码实现:

P = [30,35,15,25,10,20]
M = [[0]*6 for i in range(6)]
S = [[0]*6 for i in range(6)]

n = 6
for r in range(2,n):
    for i in range(1,n-r+1):
        j=r+i-1
        M[i][j]=M[i+1][j]+P[i-1]*P[i]*P[j]
        S[i][j]=i
        for k in range(i+1,j):
            t=M[i][k]+M[k+1][j]+P[i-1]*P[k]*P[j]
            if t<M[i][j]:
                  M[i][j]=t
                  S[i][j]=k
print M[i][j]
print S[i][j]

 

posted on 2017-11-30 09:35  一意孤城  阅读(1931)  评论(0编辑  收藏  举报

导航