Java 如何计算具有未知迭代的程序的

Java 如何计算具有未知迭代的程序的,java,time-complexity,Java,Time Complexity,我有一个程序,我无法找出它的时间复杂度。 上述程序的伪代码如下: n = 10 while n > 1 print n; if n is even n = n / 2 else n = 11 * n + 1 endwhile 有人能告诉我如何找出这个程序和类似程序的时间复杂度吗?迭代的测量是不可预测的。你是对的,尽管n的不同值会产生不同的迭代。(此处为在线编译器) 因此,在您的例子中,您需要根据起始值和乘数计算int溢出为负值所需的迭代次数 您需要根据n的模式将您

我有一个程序,我无法找出它的时间复杂度。 上述程序的伪代码如下:

n = 10
while n > 1
  print n;
  if n is even
   n = n / 2
  else
   n = 11 * n + 1
endwhile

有人能告诉我如何找出这个程序和类似程序的时间复杂度吗?迭代的测量是不可预测的。

你是对的,尽管n的不同值会产生不同的迭代。(此处为在线编译器)

因此,在您的例子中,您需要根据起始值和乘数计算int溢出为负值所需的迭代次数

您需要根据n的模式将您的算法重写为一系列for循环,即迭代次数(而不是原始的“n”数),作为您的n值

您需要将算法分解为不同的操作。你可以看到实际上有一种模式

例如,每个操作的计算方法如下:

  • 这些n*2(2,4,8,16等)在n^0.5(1,2,3,4,…)中求解
  • 那些n*3 (3,6,12,24等)在72+(n/3)(73,74,75,…)中求解
  • 这些n*5(5,10,20等)在(61,62,63,…)中求解
  • 这些n*7(7,14,28等)在(56,57,58,…)中求解
等等

把这些加起来,取算法的最高O。我的猜测是,去掉所有常数后,值将是O(N)

基于


虽然n的不同值将产生不同的迭代,但您是对的。(此处为在线编译器)

因此,在您的例子中,您需要根据起始值和乘数计算int溢出为负值所需的迭代次数

您需要根据n的模式将您的算法重写为一系列for循环,即迭代次数(而不是原始的“n”数),作为您的n值

您需要将算法分解为不同的操作。你可以看到实际上有一种模式

例如,每个操作的计算方法如下:

  • 这些n*2(2,4,8,16等)在n^0.5(1,2,3,4,…)中求解
  • 那些n*3 (3,6,12,24等)在72+(n/3)(73,74,75,…)中求解
  • 这些n*5(5,10,20等)在(61,62,63,…)中求解
  • 这些n*7(7,14,28等)在(56,57,58,…)中求解
等等

把这些加起来,取算法的最高O。我的猜测是,去掉所有常数后,值将是O(N)

基于


这似乎是Collatz猜想的一个变种。必须执行的迭代次数等于总停止时间。wiki页面上还声明,不知道是否每个数字最终都达到1

您的案例略有不同,因为它使用了不同的因素。它使用11而不是3。我们可以尝试各种不同的因素。如果您使用5而不是11(或3),并从
n=5
开始,则会得到一个序列,该序列会自动重复

  5 ->  5 * 5 + 1 = 26
 26 ->     26 / 2 = 13
 13 -> 5 * 13 + 1 = 66
 66 ->     66 / 2 = 33
 33 -> 5 * 33 + 1 = 166
166 ->    166 / 2 = 83
 83 -> 5 * 83 + 1 = 416
416 ->    416 / 2 = 208
208 ->    208 / 2 = 104
104 ->    104 / 2 = 52
 52 ->     52 / 2 = 26
 26 ->     26 / 2 = 13 (back to line 2)
当对两个奇数尝试同样的因子11时,似乎会产生发散序列。这意味着它不会停止(除非它溢出您的整数类型),并在不进入循环的情况下继续增长。剩下要做的就是证明这种情况发生了(也许是一些数学证明),这可能是一项容易的任务,也可能不是一项容易的任务

通常,您需要使用所讨论的算法的特定细节来说明可能发生的迭代次数有一定的限制。例如,如果问题使用5而不是11,那么答案是您的程序将在某些输入上永远循环。任何
2**k*5
都会导致无限循环,因此在大O表示法中,不存在可以作为时间复杂度有效边界的函数


科拉兹猜想:

这似乎是科拉兹猜想的一个变体。必须执行的迭代次数等于总停止时间。wiki页面上还声明,不知道是否每个数字最终都达到1

您的案例略有不同,因为它使用了不同的因素。它使用11而不是3。我们可以尝试各种不同的因素。如果您使用5而不是11(或3),并从
n=5
开始,则会得到一个序列,该序列会自动重复

  5 ->  5 * 5 + 1 = 26
 26 ->     26 / 2 = 13
 13 -> 5 * 13 + 1 = 66
 66 ->     66 / 2 = 33
 33 -> 5 * 33 + 1 = 166
166 ->    166 / 2 = 83
 83 -> 5 * 83 + 1 = 416
416 ->    416 / 2 = 208
208 ->    208 / 2 = 104
104 ->    104 / 2 = 52
 52 ->     52 / 2 = 26
 26 ->     26 / 2 = 13 (back to line 2)
当对两个奇数尝试同样的因子11时,似乎会产生发散序列。这意味着它不会停止(除非它溢出您的整数类型),并在不进入循环的情况下继续增长。剩下要做的就是证明这种情况发生了(也许是一些数学证明),这可能是一项容易的任务,也可能不是一项容易的任务

通常,您需要使用所讨论的算法的特定细节来说明可能发生的迭代次数有一定的限制。例如,如果问题使用5而不是11,那么答案是您的程序将在某些输入上永远循环。任何
2**k*5
都会导致无限循环,因此在大O表示法中,不存在可以作为时间复杂度有效边界的函数


科拉茨猜想:

这是可以预测的。你可以写下
n
是如何变化的。或者推导出一个数学公式。话虽如此,我甚至不确定这是否会终止。可能是这样,但只有当
n
变成2的幂时,因此,它只在
if
中出现,而不在
else
中出现。所述程序中的计数数为61…在这种情况下,如何推导数学公式,或者所述程序的时间复杂度是多少。while循环中是否有
if..else
子句?如果是,请缩进。@AkshayaAmar这是正确的问题。因为你的程序总是要经过61次迭代。正如我所说,这不是不可预测的。复杂性是O(n),因为任何数量的线性迭代复杂性都是O(n),这是绝对可预测的。你可以写下
n
是如何变化的。或者推导出一个数学公式。有了这个
  5 ->  5 * 5 + 1 = 26
 26 ->     26 / 2 = 13
 13 -> 5 * 13 + 1 = 66
 66 ->     66 / 2 = 33
 33 -> 5 * 33 + 1 = 166
166 ->    166 / 2 = 83
 83 -> 5 * 83 + 1 = 416
416 ->    416 / 2 = 208
208 ->    208 / 2 = 104
104 ->    104 / 2 = 52
 52 ->     52 / 2 = 26
 26 ->     26 / 2 = 13 (back to line 2)