天天看點

《算法技術手冊》一2.4.6 二次方的算法性能

現在考慮一個類似的問題:兩個n位的整數相乘。例2-4展示了使用國小課堂上學過的算法實作的乘法運算,其中n位數字的表示方法與之前的加法一樣。

例2-4:mult乘法的Java實作

public static void mult (int[] n1, int[] n2, int[] result) {

int pos = result.length-1;

// 清除所有的值

for (int i = 0; i < result.length; i++) { result[i] = 0; }

for (int m = n1.length-1; m>=0; m--) {

int off = n1.length-1 - m;

for (int n = n2.length-1; n>=0; n--,off++) {

}

同樣的,這裡也會給出另外一種實作算法——times。這種算法避免了取模運算的高費用,并且忽略了當n1[m]等于0時不必要的内層計算(注意,這裡并沒有給出times算法實作,讀者可以在提供的代碼庫中找到它)。times算法包含了203行生成的Java代碼來消除兩個取模操作。那麼在需要額外的費用維護和管理生成代碼時,這種衍生算法還能夠減少總的性能費用嗎?

表2-4給出了這些乘法算法的性能,乘法所使用的資料與加法使用的随機生成資料一緻。圖2-4采用圖形化的方式來描述算法性能,可以看到,抛物曲線是平方級算法的典型标志。

《算法技術手冊》一2.4.6 二次方的算法性能
《算法技術手冊》一2.4.6 二次方的算法性能

圖2-4:比較mult和times

如圖2-4所示,雖然times衍生算法的速度是mult算法的1/2,但是times和mult展現了相同的漸近性能。mult2n / multn的比率大約是4,這證明了乘法的性能是平方級的。我們定義t(n)表示乘法算法在輸入規模為n時的實際執行時間。根據這個定義,對于所有的n > n0來說,必然存在某些常數c(c > 0),滿足t(n) ≤ c*n2。我們不需要知道c和n0的實際值是多少,隻需要知道它們必然存在即可。這個mult算法實作在我們的平台上執行時,常數c為1/7,n0為16。

需要再次說明的是,修改算法實作來提升效率并不會改變算法是平方級性能的事實。盡管如此,還是有其他的算法(Zuras,1994)可以讓n位數相乘的明顯速度快于平方級。對于像資料加密這種需要頻繁實作大數乘法的應用,這類算法非常重要。