1. Karatsuba乘法
Karatsuba 乘法是一種快速乘法。此算法在1960年由 Anatolii Alexeevitch Karatsuba 提出,並於1962年得以發表。此算法主要用於兩個大數相乘。普通乘法的複雜度是 n²,而 Karatsuba 算法的複雜度僅爲 3nlog2(3)
2. 算法原理
可以注意到 AD +BC 這個計算需要兩個 O(n²/4) 的乘法和一個 O(n) 的加法。
在這樣的組合中因爲AC,BD已知,我們發現僅僅通過一個O(n²/4)乘法和四個O(n)加(減)法就可以得到AD+BC的值,從而使整體的算法複雜度從O(n²)降低到了O(n^ log2(3))約爲O(n^1.585)。看似很小的改變,但是當n足夠大時,這點微小的改變將是驚人的。在這裏其實體現的是分治的思想,這在算法設計中是十分重要的。
3. 實現思路
1、分解。將大整數X、Y(分別爲n,m位)分別爲A、B、C、D。值得注意的是如果位數n或m爲奇數,則A爲前n/2+1或m/2+1位,n/2或m/2向下取整;
即:X = A * 10^(n/2) + B
如:12345 = 123 * 10^2 + 45
2、計算。分別計算AC、BD,並且利用AC和BD計算AD+BC;
3、求解:
4. 代碼實現
由於現階段學習不夠,暫時實現m = n的算法,即AD*BC有相同的權重,可以直接合並。
from time import clock
num1 = input("Enter number 1: ")
num2 = input("Enter number 2: ")
def decompose(number):
decompose_list = [] # 列表中存儲三個元素,分別對應A B n,即三個分解元素
length = len(number) // 2
decompose_fator_1 = int(number[:-length])
decompose_fator_2 = int(number[-length:])
decompose_list.append(decompose_fator_1)
decompose_list.append(decompose_fator_2)
decompose_list.append(length)
return decompose_list
def karatsuba(number1, number2):
decompose_number1_list = decompose(number1) # 得到兩個數字的分解元素
decompose_number2_list = decompose(number2)
multiplication_item_1 = decompose_number1_list[0] * decompose_number2_list[0] # A*C
multiplication_item_3 = decompose_number1_list[1] * decompose_number2_list[1] # B*D
multiplication_item_2 = (decompose_number1_list[0] + decompose_number1_list[1]) * \
(decompose_number2_list[0] + decompose_number2_list[1]) - \
(multiplication_item_1 + multiplication_item_3) # AD + BC
final_result = multiplication_item_1 * 10 ** (decompose_number1_list[2] + decompose_number2_list[2]) + \
multiplication_item_2 * 10 ** (decompose_number1_list[2]) + multiplication_item_3
return final_result
# Karatsuba 算法並測試用時
t1 = clock()
result = karatsuba(num1, num2)
t2 = clock()
print("{} use time: {:.8f}".format(result,t2-t1))
# 普通乘法並測試用時
t3 = clock()
result = int(num1) * int(num2)
t4 = clock()
print("{} use time: {:.8f}".format(result,t4-t3))
結果如下:
Enter number 1: 12345689876547569854286143872164128698597216489251481206087986159235912541286401264512461206
Enter number 2: 12345689876547569854286143872164128698597216489251481206087986159235912541286401264512461206
152416058527889150589226315964635192601955113572897805590333888068233090059952684388567699601213779712747569488885143415310709652982182419756785791500416890857105662561345255654974436 use time: 0.00559602
152416058527889150589226315964635192601955113572897805590333888068233090059952684388567699601213779712747569488885143415310709652982182419756785791500416890857105662561345255654974436 use time: 0.01832301
可以看出使用Karatsuba能夠節省很多運行時間