【问题标题】:Time complexity of a loop with value increasing in powers of 2值以 2 的幂增加的循环的时间复杂度
【发布时间】:2020-04-01 17:42:13
【问题描述】:
for(i=1;i<=n;i=pow(2,i)) { print i }

这个的时间复杂度是多少?

kth 值的近似值 i 将是 pow(2,(pow(2,pow(2,pow(2, pow(2,pow(2,...... k times)))))))

上面的值,比如说kth value of i &lt; n,如何解决k

【问题讨论】:

  • 这是一个名为 tetration 的函数的实例。没有使用我们最熟悉的函数的解决方案,因此必须定义一个新函数:superlogarithm, or slog。因此答案是这个复杂度是 O(slog2 n)。
  • 感谢您向我介绍此功能。如果您可以将此作为答案发布,很高兴接受它作为答案,因为这正是我寻找的答案。
  • 请注意,除非 i 大于 63,否则不应使用 pow(2,i)。请改用 1 &lt;&lt; i
  • @JamesReinstateMonicaPolk 在您的评论中很好地捕捉和有效信息,但由于错误的结束条件而不是四分法,所以不需要slog ...
  • @phuclv 2^63 确实是一个很大的数字,但经过 5 次迭代后达到了... :-)

标签: algorithm math time-complexity exponentiation


【解决方案1】:

你所拥有的类似于tetration(2,n),但不是它,因为你的结束条件错误。

复杂性很大程度上取决于领域和实现。从您的示例代码中,我推断出 real domainintegers

这个函数增长得非常快,所以在 5 次迭代后你需要 bigints,即使 +,-,*,/,&lt;&lt;,&gt;&gt; 不是 O(1)。 pow 和 print 的实施也有很大的影响。

如果是小的n&lt;tetration(2,4),您可以假设复杂度是O(1),因为对于这么小的 n 没有渐近可言。

注意pow 在大多数语言中是浮点数,并且支持2 by i 可以转换为简单的位移,因此假设如下:

for (i=1;i<=n;i=1<<i) print(i); 

我们可以使用i 的先前状态来计算1&lt;&lt;i,如下所示:

i0=i; i<<=(i-i0); 

但如此大的数字并没有加速。

现在 decadic print(i) 的复杂度是以下之一:

O( log(i))               // power of 10 datawords (like 1000000000 for 32 bit)
O((log(i))^2)            // power of 2 datawords naive print implementation
O( log(i).log(log(i)))   // power of 2 datawords subdivision or FFT based print implementation

位移1&lt;&lt;i和比较i&lt;=n的复杂度是:

O(log(i))                // power of 2 datawords

因此为print 选择2 个数据字的最佳实现会导致迭代:

O( log(i).log(log(i) + log(i) + log(i) ) -> O(log(i).log(log(i)))

乍一看,我们会认为我们需要知道 kn 的迭代次数:

n = tetration(2,k)
k = slog2(n)

或与Ackermann function直接相关的Knuth's notation

n = 2↑↑k
k = 2↓↓n

但是与循环内的东西的内部复杂性相比,迭代次数是如此之少,并且下一次迭代增长如此之快,以至于上一次迭代是下一次迭代的可忽略不计的一部分,因此我们可以忽略它们,只考虑最后一次/迭代...

在所有这些假设之后,我得到了最终的复杂性:

O(log(n).log(log(n)))

【讨论】:

  • 我真的不明白你的论点,即结束条件意味着这不是四分法。我没有对实施做出任何假设。你是正确的,当 exponent 达到 2**65536 时,任何传统的 bigint 实现都会被淹没。然而,其他表示是可能的,包括符号或纯粹的四分法。很难判断 OP 是在使用类似代码的伪代码,还是实际上考虑到了真正的语言。
  • 除非我误解了当前编写的循环,否则在循环 k 次迭代后 i 的值为 2↑↑k
  • @JamesReinstateMonicaPolk 是的~n=2↑↑k 但在这种情况下k 是未知的,n 的边界是已知的,四分法有k 已知和n 未知...跨度>
  • 我确定你是对的,但我只是不明白。与其不断地打扰你,我只是盯着这个直到我明白为止。谢谢。
  • @JamesReinstateMonicaPolk :) 嘿知道这种感觉通常是一些睡眠和/或茶或更浓的东西会有所帮助......如果不是而且它并不重要,我通常会放弃这种情况......还有很多其他的有趣的东西没有必要被困在一个单一的......
猜你喜欢
  • 1970-01-01
  • 2021-11-18
  • 2013-12-08
  • 2013-12-08
  • 2017-04-11
  • 2016-12-17
  • 1970-01-01
相关资源
最近更新 更多