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能够节省很多运行时间