動態規劃 矩陣連乘問題

2021-10-02 10:18:55 字數 2961 閱讀 8862

在矩陣乘法中,不同的加括號方式的計算順序可能會有不同的計算次數。

例如a:10×100,b:100×5,c:5×50

以(ab)c計算時,需要10×100×5+10×5×50=7500

以a(bc)計算時,需要100×5×50+10×100×50=75000

顯然第一種計算方式計算次數更少,矩陣連乘問題就是求出最佳匹配的順序。

我們將矩陣的維數記錄到陣列p中。為了節省空間,且根據矩陣乘法的規則,我們將前矩陣的列數和後矩陣的行數合併,例如上例的a,b,c,記錄到p中就變成了:

p:[10, 100, 5, 50]

p[0],p[1]即為a矩陣的維,p[1],p[2]為b矩陣的維。依此類推。

此外,我們再建立兩個二維陣列m和s,行號為i,列號為j,m[ i ][ j ]是指從 i 到 j 的最小乘次,s[ i ][ j ]記錄這次乘法從**斷開。

由於j一定要大於i,所以兩個陣列都使用右上方。本次演算法的主要思想是由小區域直接被大區域查詢並決定最後採用何處斷開才能獲取最小乘次。因此方向是由小區域到大區域,從做下到右上。

下面進入正題,我將課本上的例子掏出來,大家也好理解。

a1a2

a3a4

a5a6

30×35

35×15

15×5

5×10

10×20

20×25

陣列p = [30, 35, 15, 5, 10, 20, 25]

下圖是陣列m和陣列s的計算次序。是由底層到高層的。

為了保證每次是在同一條對角線上,我們引入r作為第乙個迴圈引數,跑動在每一條對角線上的 i 理所應當的成為第二個迴圈引數。

下表是r, i, j的關係。ri

j112

1231

34……

…415

4265

16按照規律大家應該知道外側迴圈該怎麼寫了8.

接下來介紹m[ i ] [ j ]的計算方法:

若i = j,m[ i ][ j ] = 0;

在其他情況下,取k∈[i, j]迴圈,取

m[ i ][ k ] + m[ k + 1][ j ] + pi-1*pk*pj的最小值

這個式子的意思是,在當前區域內每個斷點都斷開一次,計算每種情況取最小值。同時在s[ i ][ j ]中記錄在何處斷開。

舉個例子,要計算a2a3a4a5的最小乘次,即m[2][5]。

a2(a3a4a5) :m[2][2]+m[3][5]+p1p2p5 = 13000

(a2a3)(a4a5):m[2][3]+m[4][5]+p1p3p5 = 7125

(a2a3a4)a5 :m[2][4]+m[5][5]+p1p4p5 = 11375

得知最小值7125,記錄到m[2][5]中,同時斷點為3,s[2][5] = 3。

在這之中,k成為了第3個迴圈引數,所以該演算法的時間複雜度為o(n3)

接下來是**部分:

def

matrix_chain

(p, n, m, s)

:for r in

range(1

, n)

:# r是作為標記當前對角線方向的線i和j之間的關係

for i in

range(1

, n-r+1)

:# i是行號,在每輪對角線中,i所能觸及的最大的行號依次遞減

j = i + r # j是列號,由i和r共同確定

m[i]

[j]= m[i+1]

[j]+ p[i-1]

*p[i]

*p[j]

# m[i][j]初始值是自身×之後的結果

s[i]

[j]= i # s[i][j]初始值是從自身斷開

for k in

range

(i, j)

:# k在i和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

deftraceback

(i, j, s)

:if i == j:

print

(i, end='')

return

print

('('

, end='')

traceback(i, s[i]

[j], s)

traceback(s[i]

[j]+

1, j, s)

print

(')'

, end='')

if __name__ ==

'__main__'

: p =[30

,35,15

,5,10

,20,25

] m =

s =for i in

range(0

,7):

))for j in

range(0

,7):

m[i]0)

s[i]0)

matrix_chain(p,

6, m, s)

traceback(1,

6, s)

矩陣連乘 動態規劃 動態規劃解矩陣連乘問題

一.矩陣鏈事例 矩陣鏈問題主要涉及的時在多個矩陣相乘,如何通過相乘的順序來減少程式執行。二.例題分析 這次分析過程按照動態規劃的三個基本條件來逐步解答 1 尋找最優子結構 假設我們已經找到父矩陣鏈最優解,當我們劃分到最後一步時都是兩個子矩陣鏈 分別被括號包圍 相乘,如 a1a2a3a4 a5a6a7...

python矩陣連乘 動態規劃 矩陣連乘問題

一 問題描述 給定n個數字矩陣a1,a2,an,其中ai與ai 1是可乘的,設ai是pi 1 pi矩陣,i 1,2,n。求矩陣連乘a1a2.an的加括號方法,使得所用的乘次數最少。例子三個矩陣連乘,可以有 a1a2 a3和a1 a2a3 兩種方法求積 乘法次數分別為 p0p1p2 p0p2p3和p0...

動態規劃 矩陣連乘問題

給定n 1個矩陣 a0,a1,a2,an 1 其中ai與ai 1是可乘的,i 0,1,2,n 2。矩陣乘法滿足結合律。考察這n個矩陣的連乘積,得出運算次數最少的結合。首先,考慮兩個矩陣相乘。如果a b兩個矩陣可以相乘,那麼a b的形式必定滿足 a p q b q r 設c a b,那麼c滿足c p ...