【问题标题】:Karatsuba multiplication in Python : execution timePython中的Karatsuba乘法:执行时间
【发布时间】:2014-07-14 14:19:52
【问题描述】:

我最近学习了 Karatsuba 乘法。为了充分理解这个概念,我尝试用 Python 编写代码,并将运行时间与经典乘法进行比较。尽管结果相同,但 karatsuba 的执行时间仍然是最低的,尽管我使用的是递归调用。我的方法有什么问题?一些帮助肯定会让我更多地了解算法设计。

最好的

日本

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)

【问题讨论】:

  • 您使用了哪些输入和结果?可以发一下吗?
  • 你把它比作什么?

标签: python algorithm optimization multiplication


【解决方案1】:
  1. Karatsuba 乘法比经典二进制乘法的开销更大

    复杂性更好,但开销导致 karatsuba 对于更大的数字更快。 Karatsuba 编码的阈值操作数大小越小越好。

  2. 我在您的代码中看到您将数字转换为字符串以获取数字计数

    这是非常慢的操作,特别是对于大数字使用对数(恒定的二进制与十进制数字的比率)和二进制位计数。查看here 了解如何更快地编写 Karatsuba 代码(代码使用 C++

  3. pow 的使用

    另一个减慢使用 10 的幂表代替

  4. 你把它比作什么? (最初由 Padraic Cunningham 提出)

    Karatsuba 更快,因为它对较低位计数的变量进行操作!!!我根本没有在 Phyton 中编码,所以我可能会遗漏一些东西(比如任意 int),但我看不到任何地方通过降低位数来降低数据类型 所以你会总是慢!!!。同样不错的是添加慢速乘法示例,您将时间与二进制或基数乘法进行比较......(添加您使用的内容)。如果您只使用 * 运算符,那么如果您使用的是一些 bigint 库,那么您可能会将 KaratsubaKaratsuba 甚至 Schönhage-Strassen强>

  5. 时间测量

    你如何衡量时间?如果不循环计算N 次,则时间应该大于 10 毫秒并测量整个事情以避免准确性问题。如果你不知道我在写什么,还要考虑 OS 的调度粒度看看 here

【讨论】:

    【解决方案2】:

    如果小于 10,您的算法应该乘以数字:

     if int(len_x) < 10 or int(len_y) < 10:
    

    karatsuba1 是您的原始代码。 karatsuba 正在使用if int(len_x) &lt; 10 or int(len_y) &lt; 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
    

    【讨论】:

      猜你喜欢
      • 2015-09-29
      • 2017-05-23
      • 1970-01-01
      • 2020-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-06
      相关资源
      最近更新 更多