動態規劃之矩陣連乘最優化問題
阿新 • • 發佈:2019-01-29
1.問題描述
輸入:<A1,A2, ... ,An>,其中Ai是 pi-1 * pi 矩陣
輸出:計算 A1*A2*...*An 的最小代價方法
2.演算法分析
假設m(i,j)表示計算Ai~j的最小乘法數,那麼m(i,j)就等價於min( m(i,k) + m(k+1,j) + pi-1*pk*pj ),因此當 i=j 時有m(i,j)=0.
初始化問題:將對角線上元素m(i,i)設定為0,然後沿對角線遞推子結構。
3.程式碼實現
import numpy as np # 矩陣乘法的階數 matrix = np.array([[2,3],[3,5],[5,3],[3,2],[2,6]]) #參與乘法運算的矩陣數目 num = len(matrix) # 儲存矩陣乘法的代價 mlti_order = np.zeros(num*num).reshape(num,-1) # 儲存矩陣乘法的順序,即k值 mlti_k = np.zeros(num*num).reshape(num,-1) #預定義一個最大代價,在比較取不同K值時需要用到 INF = 1000 # 遞推子結構 for r in range(num - 1): #由於主對角線已被初始化為0,因此還需要遞推num-1個對角線, i = 0 j = r + 1 while (i < num - r) & (j < num): #對於第r+1條對角線求每個m(i,j)的值 k=i mlti_order[i][j] = INF while k < j: #對每個m(i,j),求某個k值使m(i,k)+m(k+1,j)+pi-1*pk*pj最小 value = mlti_order[i][k] + mlti_order[k+1][j] + matrix[i][0]*matrix[k][1]*matrix[j][1] if value < mlti_order[i][j]: mlti_order[i][j] = value mlti_k[i][j] = k #儲存這個K值 k += 1 i += 1 j += 1 print '這些矩陣相乘的最小代價為:',mlti_order[0][num-1], def printOrder(order, i, j): if i == j: print 'A',i+1, else: print '(', k = int(order[i][j]) printOrder(order, i, k) printOrder(order, k+1, j) print ')', print ',運算順序為:',printOrder(mlti_k, 0, num-1)
4.時間複雜性
-計算代價的時間:(r,i,k)三層迴圈,每層至多n-1步,為O(n^3)
-構造最優解的時間:O(n)
-總時間複雜度:O(n^3)
5.空間複雜性
-使用陣列mlti_order 和 mlti_k來存放代價和解,為O(n^2)