【问题标题】:Measuring Big O of multiplication in Python在 Python 中测量乘法的大 O
【发布时间】:2015-06-30 13:28:14
【问题描述】:

据我了解,乘法的复杂度是二次的,所以如果将两个 1 位数字相乘将有 1 个操作,两个 2 位数字相乘将有 4 个操作,两个 3 位数字 9操作等等。

我想通过简单地将两个数字相乘的程序的执行时间来了解这种复杂性。没想到,不管数字大小,执行时间都是一样的。

import time

num1 = 135
num2 = 342

start = time.time()
total = num1 * num2
finish = time.time()
elapsed = finish - start

print elapsed

所以如果我将两个 3 位数字或两个 30 位数字相乘,结果是 9.53674316406e-07

我误会了什么?

【问题讨论】:

  • “据我所知,乘法的复杂度是二次的” - 是什么让你这么认为?以十进制计算数字毫无意义,一方面,因为计算机将处理数字的二进制表示。
  • 为什么投反对票?这是一个有效的问题。
  • 按照这个解释@jonrsharpe stackoverflow.com/questions/487258/…
  • 对于大数字它应该。我认为他对小数字感到困惑。
  • Python 使用 Karatsuba 乘法算法进行大整数乘法,该算法将数字相乘 O(n^1.585),而不是 O(n^2)。

标签: python math big-o


【解决方案1】:

您的数字太小了,无法在乘以它们的时间上表现出任何差异。尝试一些适当大小的数字,大约为 10106

例如:

import time

for k in range(10):
    num = 10**(10**k)

    start = time.time()
    total = num * num
    finish = time.time()
    elapsed = finish - start

    print k, elapsed

在我的机器上输出:

0 2.86102294922e-06
1 5.00679016113e-06
2 2.14576721191e-06
3 7.86781311035e-06
4 0.000285148620605
5 0.010409116745
6 0.391373157501
7 15.7926459312

(我还在等8)。

【讨论】:

    【解决方案2】:

    你是正确的,对于大数乘法是二次的(或者甚至更好的算法至少>O(n))。只要它们适合 64 位数字,您可能不会看到任何变化。您遇到的两个问题是 64 位数字最多可以容纳 9.223372e+18(一个 19 位数字),而您的 30 位数字将是两个 64 位数字。尝试使用几个 64 位数字(比如 10000,这将是一个 180000 位数字):

    import time
    import random
    
    for i in range(0, 190000, 10000):
        a = random.randint(10**i, 10**(i+1)-1)
        b = random.randint(10**i, 10**(i+1)-1)
    
        start = time.time()
        c = a*b
        end = time.time()
    
        print i, str(c)[0], end-start # str(c)[0] just in case optimization on c (unlikely)
    

    结果:

    0 1 0.0
    10000 3 0.000855922698975
    20000 5 0.00253701210022
    30000 1 0.00445008277893
    40000 4 0.00767087936401
    50000 3 0.00982689857483
    60000 1 0.0133669376373
    70000 9 0.0174329280853
    80000 4 0.0230648517609
    90000 3 0.0251250267029
    100000 4 0.0296058654785
    110000 4 0.0344429016113
    120000 3 0.0401389598846
    130000 1 0.0457019805908
    140000 2 0.0524950027466
    150000 1 0.0619490146637
    160000 5 0.0693421363831
    170000 2 0.068922996521
    180000 2 0.0755639076233
    

    基于 90000 和 180000 的结论是 >O(n) 但是

    【讨论】:

      猜你喜欢
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多