我最近学会了Karatsuba乘法。为了完全理解这个概念,我试图用Python编写代码,并将运行时间与经典乘法进行比较。虽然结果是相同的,但karatsuba的执行时间仍然是最低的,尽管我使用的是递归调用。我的做法有什么问题?一些帮助肯定会让我更多地了解算法设计。
最佳
JP
print('Karatsuba multiplication in Python')
x=raw_input("first_number=")
y=raw_input("second_number=")
print('------------------------')
x=int(x)
y=int(y)
import math
import time
def karatsuba(x,y):
x=str(x)
y=str(y)
len_x=len(x)
len_y=len(y)
if(int(len_x)==1 or int(len_y)==1):
return int(x)*int(y)
else:
B=10
exp1=int(math.ceil(len_x/2.0))
exp2=int(math.ceil(len_y/2.0))
if(exp1<exp2):
exp=exp1
else:
exp=exp2
m1=len_x-exp
m2=len_y-exp
a=karatsuba(int(x[0:m1]),int(y[0:m2]))
c=karatsuba(int(x[m1:len_x]),int(y[m2:len_y]))
b=karatsuba(int(x[0:m1])+int(x[m1:len_x]),int(y[0:m2])+int(y[m2:len_y]))-a-c
results=a*math.pow(10,2*exp) + b*math.pow(10,exp) + c
return int(results)
start_time=time.time()
ctrl = x*y
tpt=time.time() - start_time
print x,'*',y,'=',ctrl
print("--- %s seconds ---" % tpt)
start_time=time.time()
output=karatsuba(x,y)
tpt=time.time() - start_time
print 'karatsuba(',x,',',y,')=',output
print("--- %s seconds ---" % tpt)
答案 0 :(得分:5)
Karatsuba乘法比经典二进制乘法具有更大的开销
复杂性更好但是开销导致 karatsuba 对于更大的数字更快。 Karatsuba 编码越好,阈值操作数越小。
我在您的代码中看到您将数字转换为字符串以获取数字
非常慢操作,特别是对于大数字,使用对数(常量二进制到十进制数字比率)和二进制位计数。查看here有关如何更快地编码 Karatsuba 的想法(代码位于 C ++ )
使用pow
另一个减速使用权力表10而不是
你在比较什么? (最初由Padraic Cunningham提出)
Karatsuba 更快,因为它可以在较低的位数变量上运行!我根本没有在 Phyton 中编码,所以我可能会遗漏一些东西(比如任意int),但是我没有看到你通过降低位数降低数据类型的任何地方所以你将成为总是慢!!! 。另外很好的是添加慢速乘法的例子,你要比较二进制或基数乘法的时间...(添加你使用的)。如果您只使用*
运算符,那么如果您使用的是bigint lib,那么您可以将 Karatsuba 与 Karatsuba 或甚至Schönhage-Strassen进行比较强>
时间测量
你如何衡量时间?如果不循环计算N
次,则时间应该大于10ms,并测量整个事物以避免准确性问题。如果您不知道我写的是什么,请记住操作系统的调度粒度here
答案 1 :(得分:2)
如果&#是你的算法,你的算法应该乘以数字。 10:
if int(len_x) < 10 or int(len_y) < 10:
karatsuba1
是您的原始代码。 karatsuba
正在使用if int(len_x) < 10 or int(len_y) < 10
In [17]: %timeit karatsuba1(999,999)
100000 loops, best of 3: 13.3 µs per loop
In [18]: %timeit karatsuba(999,999)
1000000 loops, best of 3: 1.77 µs per loop