五、分治法应用--矩阵乘法
生活随笔
收集整理的這篇文章主要介紹了
五、分治法应用--矩阵乘法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1 樸素算法
這個算法就是矩陣乘法的定義:
- 很容易看出這個算法復雜度是Θ(n3)\Theta(n^3)Θ(n3)。
2 遞歸算法
分治法首先是從分割問題開始的,得到數學上的遞歸關系后,然后使用遞歸的方式實現。
由上面的數學性質,可以使用遞歸實現:
- T(n)=8T(n/2)+Θ(n2)T(n)=8T(n/2)+\Theta(n^2)T(n)=8T(n/2)+Θ(n2),應用主定理可知,T(n)=Θ(n3)T(n)=\Theta(n^3)T(n)=Θ(n3),沒有什么進步,不過這里分割思路是沒有問題的,只不過還有一步技巧性較強的變換在里面。
3 Strassen’s algorithm for matrix multiplication
1969年,斯特拉森(V.Strassen)利用分治策略并加上數學處理設計出了一種時間復雜度是O(n2.81)O(n^{2.81})O(n2.81)(準確地說是O(nlog7)O(n^{log7})O(nlog7))的矩陣相乘算法,宣稱在時間復雜度數量級上有所突破。此結果一發布,立即震動了整個數學界。
整個算法的核心是在分塊的基礎上做了一步變換,這個變換甚至高中生都可以看懂,但是只有牛人想的到。
得到上面的問題分割方式后,仿照遞歸算法容易實現。
- T(n)=7T(n/2)+Θ(n2)T(n)=7T(n/2)+\Theta(n^2)T(n)=7T(n/2)+Θ(n2),應用主定理可知,T(n)=Θ(nlog7)T(n)=\Theta(n^{log7})T(n)=Θ(nlog7)。
4 實現
為便于說明問題這里僅考慮矩陣階數為2n2^n2n的情況。
# -* coding: utf-8 -*-import numpy as np from timeit import default_timer as timerdef STRASSEN_MATRIX(A, B):n = A.shape[0]C = np.array([0] * (n * n)).reshape((n, n))d = int(n / 2)if n == 1:C[0, 0] = A[0, 0] * B[0, 0]else:S1 = B[0:d, d:n] - B[d:n, d:n]S2 = A[0:d, 0:d] + A[0:d, d:n]S3 = A[d:n, 0:d] + A[d:n, d:n]S4 = B[d:n, 0:d] - B[0:d, 0:d]S5 = A[0:d, 0:d] + A[d:n, d:n]S6 = B[0:d, 0:d] + B[d:n, d:n]S7 = A[0:d, d:n] - A[d:n, d:n]S8 = B[d:n, 0:d] + B[d:n, d:n]S9 = A[0:d, 0:d] - A[d:n, 0:d]S10 = B[0:d, 0:d] + B[0:d, d:n]P1 = STRASSEN_MATRIX(A[0:d, 0:d], S1)P2 = STRASSEN_MATRIX(S2, B[d:n, d:n])P3 = STRASSEN_MATRIX(S3, B[0:d, 0:d])P4 = STRASSEN_MATRIX(A[d:n, d:n], S4)P5 = STRASSEN_MATRIX(S5, S6)P6 = STRASSEN_MATRIX(S7, S8)P7 = STRASSEN_MATRIX(S9, S10)C[0:d, 0:d] = P5 + P4 - P2 + P6C[0:d, d:n] = P1 + P2C[d:n, 0:d] = P3 + P4C[d:n, d:n] = P5 + P1 - P3 - P7return Cdef run_time():tic = timer()# 待測試的代碼toc = timer()print(toc - tic) # 輸出的時間,秒為單位if __name__ == '__main__':A = np.array(list(range(0, 16))).astype(int).reshape((4, 4))B = np.array(list(range(2, 18))).astype(int).reshape((4, 4))print('strassen:\n', STRASSEN_MATRIX(A, B))print('dot:\n', np.dot(A, B))運行結果:
strassen:[[ 68 74 80 86][196 218 240 262][324 362 400 438][452 506 560 614]] dot:[[ 68 74 80 86][196 218 240 262][324 362 400 438][452 506 560 614]]總結
以上是生活随笔為你收集整理的五、分治法应用--矩阵乘法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实用vba案例
- 下一篇: 线程,进程,并发,并行