计算复杂性?

时间:2013-01-16 22:21:05

标签: algorithm sorting complexity-theory asymptotic-complexity

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

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),但我不确定如何计算它,因为每次都减半。有人有什么想法吗?

3 个答案:

答案 0 :(得分:4)

如果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))

答案 1 :(得分: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(的复杂性。

答案 2 :(得分:0)

算法的复杂性是:

你的第一个循环运行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))})