计算x ^ y的运行时间

时间:2011-01-24 04:21:14

标签: algorithm big-o performance

我如何找到执行(y − 1)乘以x的基本算法的运行时间(以Big-O表示法)来查找x^y

编辑:我还需要记住每次乘法的运行时间:“假设将n-bit数字乘以m-bit数字的时间为O(mn)”。< / p>

3 个答案:

答案 0 :(得分:3)

嗯,你只需要考虑每个操作的位数并总结它们。当然,我们会做一些简单的事情,因为它不会影响大O符号的答案。

因此,x中的位数是ceiling(log2(x))(即x的对数基数2之上的下一个整数)。为简单起见,我们将此号码称为b。这意味着x大于2 ^(b-1)且小于2 ^ b。因此x ^ 2大于2 ^(2(b-1))且小于2 ^(2b)。因此,我们假设x ^ 2的大小约为2b,并且通常x ^ n的大小为nb。这非常接近正确,因为它位于n(b-1)和nb之间。

我们的第一次乘法需要时间b * b = b ^ 2。我们的第二次乘法将需要2b * b(因为x ^ 2的大小为2b而x仍然是大小b)。我们的第三个将是3b * b(因为x ^ 3的大小为3b,x仍然是大小b)。所以,一般来说,我们的第n次乘法将是nb * b。

所以我们的总和看起来像b ^ 2 + 2b ^ 2 + 3b ^ 2 + ... +(y-1)b ^ 2。我们可以将b ^ 2分解出来,给我们(b ^ 2)(1 + 2 + 3 + ... +(y-1))。对于第二项,1 + 2 + 3 + ... +(y-1),我们可以使用1 + 2 + 3 + ... + n = n(n + 1)/ 2的公式。所以我们得到(b ^ 2)(y-1)(y)/ 2。

此时我们非常接近答案,但我们想要做两件事:我们想用x和y(而不是b)来表达一切,我们希望使用big-O表示法减少事物为简单起见。 (y-1)(y)/ 2可以简化为O(y ^ 2)。 b = ceiling(log2(x)),可以简化为O(log(x))。替换回来,我们得到 O((log(x))^ 2 * y ^ 2)

当然,所有这些都假设我们使用的算法如下:

product = 1
for i = 1 to y
  product = product * x
return product

如果我们正在做一些比这更复杂和奇怪的事情:

xs = empty list
for i = 1 to y
  xs.addItem(x)
while xs is not empty
  num1 = xs.removeRandomItem
  num2 = xs.removeRandomItem
  xs.addItem(num1*num2)
return head(xs)

然后时序分析变得更加复杂。 (注意,该算法也进行y-1次乘法并得到正确的结果。)

查找x ^ y的另一种常见算法是重复平方算法,其工作方式如下:

result = 1
temp = x
while y>0
  if y mod 2 = 1
    result = result * temp
    y = y - 1
  temp = temp * temp
  y = y / 2
return result

对于那个我们每轮进行两次乘法,其中涉及两个数字,每个数字的大小为b(2 ^ n),其中n是从0开始计算的圆数(即,我们经历过的次数) while循环)。因此在第n轮中,每次乘法将花费b(2 ^ n)* b(2 ^ n)=(b ^ 2)(2 ^(2n))。但它只是上限(log2(y))轮。所以它的运行时间是(b ^ 2)(2 ^ 0)+(b ^ 2)(2 ^ 2)+(b ^ 2)(2 ^ 4)+ ... +(b ^ 2)的总和)(2 ^(2 *天花板(LOG2(Y))))。因此,我们再次将b ^ 2分解为离开(b ^ 2)(2 ^ 0 + 2 ^ 2 + 2 ^ 4 + ... + 2 ^(2 * ceiling(log2(y))))。尽管看起来很复杂,但整个第二项实际上是O(y ^ 2)。一旦我们再次替换b,我们发现这个也是O((log(x))^ 2 * y ^ 2)。因此,虽然当乘法是常数时间运算时这个算法更快,但当我们使用BigIntegers或其他任意精度类型时,它并不一定更快。这就是为什么它最常用于像矩阵乘法这样的情况,其中乘法的成本是恒定的但是很大。

答案 1 :(得分:1)

O(logy)或O(y)取决于您选择的方法,您应该开始阅读http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.4

在(y-1)次乘法O(y)步数的情况下,假设乘法是一个运算,因为加倍y的大小将导致所需的运算量加倍,这称为线性过程。

LE:在这种情况下,你将有1 * n ^ 2 + 2 * n ^ 2 + ... + y * n ^ 2。第一次将数字乘以它因此n * n = n ^ 2第二次结果n * n(大小2n)乘以数n =&gt; 2n ^ 2等等。

n ^ 2(1 + 2 + ... y)= n ^ 2 * y *(y + 1)/ 2

所以答案是O(n ^ 2 * y ^ 2)其中n = x中的位数(或n = ceil(log(x)))。

答案 2 :(得分:1)

如果每次乘法都算作单个操作,那么需要y - 1步的算法只是O(y - 1) = O(y),这是您在此问题中找到的最常见的答案。实际上,乘法不能在恒定时间内完成,所以你需要乘以你正在使用的multiplication algorithm的速度。

请注意,使用exponentiation by squaring,您可以执行少于y - 1次操作,而取幂算法可以改为O(log y)