1. 程式人生 > >演算法導論 之 貪心演算法- 矩陣鏈相乘

演算法導論 之 貪心演算法- 矩陣鏈相乘


1 引言

    在大學期間,我們學過高等數學中的線性規劃,其中有關於矩陣相乘的章節:只有當矩陣A的列數與矩陣B的行數相等時,A×B才有意義。一個m×n的矩陣A(m,n)左乘一個n×p的矩陣B(n,p),會得到一個m×p的矩陣C(m,p)。矩陣乘法滿足結合律,但不滿足交換律。

    假設現要計算A×B×C×D的值,因矩陣乘法滿足結合律,不滿足交換律,即:A、B、C、D相鄰成員的相乘順序不會影響到最終的計算結果,比如: A×(B×(C×D))、A×((B×C)×D)、(A×B)×(C×D)、A×(B×C)×D、((A×B)×C)×D,雖然組合方式不一樣,但是最終的計算結果是一致的,但改變任何成員的位置將影響到最終的計算結果。

    需要注意的是:雖然矩陣鏈相乘時,結合方式不同所得結果一致,但獲得最終結果的所花費的時間是不一樣的。假如:現有矩陣A(10,100)、B(100,5)、C(5,50),則不同結合方式的運算次數如下:

    運算次數N1[(A×B)×C] = 10*100*5+10*5*50 = 5000 + 2500 = 7500

    運算次數N2[A×(B×C)] = 100*5*50 + 10*100*50 = 25000 + 50000 = 75000

    N1:N2 = 7500 : 75000 = 1:10,經過對比可以發現:不同的矩陣相乘的結合方式在效能方面的表現差異十分懸殊。而《動態規劃 之 矩陣鏈相乘》就是針對此種問題的存在,從中選擇最佳的矩陣結合方式,提高此類問題的求解效率。

2 處理思路

    那麼針對矩陣鏈相乘的問題,怎樣才能選出最佳的結合方式呢?在《演算法導論》一書"動態規劃"的小節中給出了對此類問題的解決方案,但過程讓人費解.在此,本人將給出更加簡單,更加清晰的處理思路,以供大家參考。

   假設現有矩陣A1(50,30)、A2(30,20)、A3(20,100)、A4(100,10)、A5(10,5),要求以最快的方式計算出它們相乘的結果。


圖1 初始狀態

Step1:計算相鄰矩陣相乘的計算次數

    N[A1×A2] = 50*30*20  = 30000

    N[A2×A3] = 30*20*100 = 60000

    N[A3×A4] = 20*100*10 = 20000

    N[A4×A5] = 100*10*5  = 5000    - 最小


    由以上的計算結果可知N[A4*A4]的值最小,因此首先結合矩陣A4(100,10)和A5(10,5),得到矩陣B(100, 5)。此時所剩矩陣為:A1(50,30)、A2(30,20)、A3(20,100)、B(100,5)。


圖2 矩陣A4與A5結合

Step2:計算相鄰矩陣相乘的運算次數

    N[A1×A2] = 50*30*20  = 30000     - 不變

    N[A2×A3] = 30*20*100 = 60000     - 不變

    N[A3×B]  = 20*100*5  = 10000     - 最小

    同理,結合矩陣A3和A45,得到矩陣C(20, 5)。此時所剩矩陣為:A1(50,30)、A2(30,20)、C(20,5)。


圖3 矩陣A3與B結合

Step3:計算相鄰矩陣相乘的運算次數

    N[A1×A2] = 50*30*20 = 30000         - 不變

    N[A2×C]  = 30*20*5 = 3000           - 最小

    同理,結合矩陣A2和C,得到矩陣D(30, 5)。此時所剩矩陣為:A1(50,30)、D(30,5)。


圖4 矩陣A2與C結合

Step4:最終計算順序

    由以上3步的統計結果可知最佳的計算方式為:A1×(A2×(A3×(A4×A5))),用樹來表示計算順序的話,其結構如下圖所示:


圖5 最佳計算順序

    如果需要以最快的方式計算A1*A2*A3*A4*A5的結果的話,則只需要遍歷圖5中的二叉樹,便能找到最快的計算順序。當然如果矩陣A1、A2、A3、A4、A5有其他的行列數時,最佳計算順序可能為A1×((A2×A3)×(A4×A5)),則用二叉樹表示為:


圖6 其他可能最佳順序

有了處理思路,一切就變得簡單了...