【问题标题】:Calculating complexity?计算复杂度?
【发布时间】:2012-12-31 09:29:25
【问题描述】:

我一直在尝试计算以下函数的复杂度:

k=n;
while(k>0)
  g(n);
  k=k/2; {Comment: this is integer division, so 1/2=0}
end while;
for(j=0;j<m;j++)
  f(m);

具体来说,while 循环的复杂度。有人告诉我 g(n) 的复杂度是 O(n),但我不确定它的复杂度是多少,以及我将如何解决它.我已经意识到复杂度不会是 O(0.5n^2),但我不确定如何计算它,因为每次减半。有人有什么想法吗?

【问题讨论】:

  • 如果您的问题大小每次迭代减半,您需要进行多少次迭代才能达到问题大小为 0? IE。给定一个数字n,您需要在(整数)计算器上按多少次 /2 才能达到 0?
  • @Karel 我试过用 8 等数字表示 n/2,但 20 等数字表示 n/4,所以我不确定。
  • 这个数字实际上被称为对数(以 2 为底,除以 2)。 IE。外部循环重复 log(n) 次,其余的应该很容易 :) 另见 cs.stackexchange.com/questions/581/…
  • @KarelPetranek 我查看了那个链接,但是如果它重复 log n 次,当我使用 10 作为 n 的值时,我计算它应该运行 4 次,但我得到 log( 10) = 3.32?
  • 你不能运行一个循环 3.32 次,所以你总是需要将数字向上取整(理论上迭代的分数意味着你需要在实践中进行整个迭代)。

标签: algorithm sorting complexity-theory asymptotic-complexity


【解决方案1】:

如果g(n)是O(n),那么你的复杂度是O(n*log(n))

为了进一步解释,让我们暂时忽略 g(n)

k = n;
while(k > 0) {
    k = k / 2;
}

假设 n = 1000

那么我们会得到以下k的值

Pass | k
-------------
 0   | 1000
 1   | 500
 2   | 250
 3   | 125
 4   | 62
 5   | 31
 6   | 15
 7   | 7
 8   | 3
 9   | 1
 10  | 0 (stopped)

log(1000) = 9.96 请注意,只需 10 次迭代即可将 k 降至零。 这是一个 log(n) 计算复杂度的例子。

然后,当您在循环中添加 g(n) 时,这意味着您为每次迭代添加 O(n),这给了我们总计 O(n*log(n))

【讨论】:

  • 不一定,还要看f(m)的复杂度。
  • 是的,但是如果f(m)的复杂度不大于O(n*log(n))那么没关系。
  • 虽然 while 循环确实是 O(nlogn),但更严格的界限是 O(n)。 (O(N)是O(NlogN)的子集,while循环其实是Theta(N)
  • @KirkBackus 你能解释一下你是怎么得到nlogn的吗?我明天有考试,非常感谢。
  • @KirkBackus 如果 n=3 会怎样?那应该运行 3 次,但 log 3 = 1.58?
【解决方案2】:

while 循环的复杂度显然是O(n log n)。存在log n 迭代,因为在每次迭代结束时,k 除以 2。要获得迭代次数,请将 n 表示为 2 的幂,例如 2^x。如果2^x=n, then x = log n。这就是为什么while循环的复杂度是O(n log n)。不要混淆,因为n 不是 2 的幂,这意味着 log n 并不总是整数,您应该写,而不是 log n,[log n],其中[y] 是整数y 的一部分。您始终可以将[log n] 表示为c* log n,其中c 是一个常数,这不会改变算法的复杂性。因此,您不需要[] 函数,O(n log n) 是可以接受且正确的答案。

for 循环的复杂度取决于f(m) 的复杂度。如果 O(f(m)) 为 O(1),则循环为 O(m),但如果 O(f(m))O(m),则循环为 O(m^2)。因为f(m)也是算法的一部分,所以要确定整个代码的复杂度,需要知道f(的复杂度。

【讨论】:

    【解决方案3】:

    你的算法的复杂度是:

    您的第一个循环运行 O(logn) 次,每次迭代都必须执行 g(n)。因此需要

    O(sum{i from 0 to log(n)}{O(g(i))}). 
    

    第二个循环运行 m 次。需要:

    O(sum{j from 0 to m}{O(f(i))})
    

    你的算法的总复杂度是:

    O(sum{i from 0 to log(n)}{O(g(i))}) + O(sum{j from 0 to m}{O(f(i))})
    

    【讨论】:

      猜你喜欢
      • 2017-11-04
      • 2019-03-11
      • 2013-11-01
      • 2013-04-30
      • 1970-01-01
      • 1970-01-01
      • 2021-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多