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能夠節省很多運行時間

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