Python_算法实现_(10)Karatsuba乘法

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章