在很多機器學習或者資料探勘**中,裡面或多或少的涉及到演算法複雜度分析。進一步思考,是如何得到的呢?
很長時間裡,我也感受到比較疑惑,閱讀**過程中,在涉及到這部分內容時,會直接跳過演算法複雜度分析這快。
其一是因為比較燒腦。雖然知道複雜度分析是對演算法總體上的概況,用來進行演算法間好壞的比較(由此可見,重要性)。
其二是演算法分析基礎比較薄弱(個人主觀上也是不想的)。
演算法複雜度在《資料結構》課程中也或多或少的涉獵,說完全不知道屬於自己騙自己,簡單的一些例子還是會分析的,但當涉及到複雜的目標方程是,特別是含矩陣運算,就不知道如何分析了。也沒有領路人,不知道如何下手。隨著看的**數量上公升,慢慢摸索過程中突然就通了,知道如何去分析了。寫這篇部落格的目的希望讀者能夠明白如何對矩陣乘法進行複雜度分析,少走一些彎路。筆者先介紹2個矩陣相乘複雜度,然後介紹3個矩陣相乘複雜度,最後介紹幾篇**裡面的loss方程,如何運用矩陣乘法複雜度去分析演算法的好壞。
需要的基礎,初步了解《資料結構》第一章知識,至少知道演算法複雜度是什麼以及如何表示。
對於矩陣a(n*m),b(m*n), 這裡a(n*m)表示a是n行乘m列的矩陣。
如果a*b,那麼複雜度為o(n*m*n),即o(n^2m) 。進一步思考,為什麼呢,直接**解釋:
for(i=0;i乙個for迴圈是o(n),這裡是三個for迴圈,所以為o(n*m*n)。(ps:個人感覺還是看**比較好理解,後面三個矩陣乘法時,就會更加體會到)
對於矩陣a(m*n),b(n*m)和c(m*n), 這裡a(m*n)表示a是m行乘n列的矩陣。(ps:這裡記號和前面不同,主要方便和知乎截圖符號一致)
與(a*b)*c等價。整個過程演算法複雜度為o(m^2n) 。(一開始筆者以為是o(m^2n)*o(m^2n) = o(m^4n^2), 其實這樣理解是錯的,下面介紹)
這裡與知乎這篇一致,截圖如下:
為了方面理解,筆者直接上**,這樣清楚一點。
int a(m*n),
int b(n*m)
int c(m*n)
int d(m*m)
int e(m*n)
//先計算d=a*b
for(i=0;i同樣的,乙個for迴圈是o(n),這裡的第一次三個for迴圈,矩陣乘法複雜度為o(m*n*m)=o(m^2n)。
第二次為o(m^2n)
但因為是順序執行,所以總的複雜度是相加而不是相乘。
故為o(m^2n)+o(m^2n)
= o(2*m^2n)
= o(m^2n),在演算法分析過程中,係數可以忽略
目標方程截圖如下:
演算法複雜度為o(n^3*k + n^2*m + n*m*d), 計算方向從左到右。其中a(n*n), x(n*m) ,r(m*d), k為累加次數(相當於在外面加了乙個for迴圈,遍歷k次)
o(n^3*k)表示計算
閱讀原文會發現,這裡的
o(n^3*k + n^2*m)表示計算
o(n^3*k + n^2*m + n*m*d)則表示全部過程。
作者後面做了計算優化,把演算法負責度由o(n^3*k + n^2*m + n*m*d) 降到了o(k*e*n + n*m*d)
o( n*m*d) 表示計算
o(k*e*n)表示計算
複雜度分析 時間複雜度分析和空間複雜度分析
其實,只要講到資料結構與演算法,就一定離不開時間 空間複雜度分析。而且我個人認為,複雜度分析是整個演算法學習的精髓,只要掌握了它,資料結構和演算法的內容基本上就掌握了一半。1.時間複雜度分析 對於剛才羅列的複雜度量級,我們可以粗略地分為兩類,多項式量級和非多項式量級。其中,非多項式量級只有兩個 o ...
複雜度分析 時間複雜度 空間複雜度
執行效率是演算法的乙個重要的考量指標,演算法的執行效率用時間 空間複雜度來衡量。今天我們來學習一下複雜度的分析。通常我們可以通過執行程式來獲得演算法的真正的執行時間,這種方法我們可以稱為事後統計法,但這種方法得到的是具體的資料,測試結果很依賴測試環境,而且受資料規模影像最大。因此,我們需要乙個不需要...
複雜度分析(上)時間複雜度 空間複雜度
為了肉眼 實時 快速地來分析出 的複雜度,我們需要乙個不用具體的測試資料來測試,就可以粗略地估計演算法的執行效率的方法。時間複雜度 空間複雜度 表示演算法的執行時間與資料規模之間的增長關係。每行 對應的 cpu 執行的個數 執行的時間都不一樣,但是,我們這裡只是粗略估計,所以可以假設每行 執行的時間...