代码:
int temp = 0;
for (int h = 1; h <= n; h = h * 2)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j<=n; j++)
{
for (int k = 1; k<i; k++)
{
temp++
}
}
}
}
根据我的计算,big-O lg n * n ^ 4 。 请指导。
编辑:谢谢大家的回复。我明白我犯了什么错误。我非常感谢所有参与的人。
答案 0 :(得分:3)
for (int h = 1; h <= n; h = h * 2) // increment is pow(2). hence executed ln(n) times
{
for (int i = 1; i <= n; i++) // increment is one. Executed n times
{
for (int j = 1; j<=n; j++)// increment is one. Executed n times
{
// increment is one. Executed i times. See below
for (int k = 1; k<i; k++)
{
temp++
}
}
}
}
k
循环执行i
次。 i
的最大值为n。所以你可以认为它总是被执行n
次(过近似)
复杂度= ln(n)* n * n * n = ln * pow(n,3)
另一种看待它的方法......让我交换循环和循环
for (int h = 1; h <= n; h = h * 2) // increment is pow(2). hence executed ln(n) times
{
for (int j = 1; j <= n; j++) // increment is one. Executed n times
{
// see below
for (int i = 1; i<=n; i++)
{
for (int k = 1; k<i; k++)
{
temp++
}
}
}
}
现在看一下......(i,k)的执行总数是n*(n+1)/2
。那么现在的复杂性是什么?
h * j *(i,k)= ln(n)* n *(n *(n + 1)/ 2)== ln(n)* pow(n,3)
答案 1 :(得分:2)
只是为了踢,我用不同的n:
值运行这段代码 n temp O?
----------- -------------- ---------
1 0
10 1800 1.8 x n^3
100 3465000 3.5 x n^3
1000 4995000000 5.0 x n^3
10000 6999300000000 7.0 x n^3 (and took a LONG time!)
结论:log(n)* n ^ 3
答案 2 :(得分:1)
Knightrider基本上是对的,但如果你想要正确的数字,你就不能说&#34;我取i
&#34;的最大值。
是的,它在f(n) = O(...)
方面是正确的,但你也可以写f(n) = O(n^15)
,这也是正确的。
最后一个循环执行n次,然后执行n-1次,然后执行n-2次等,这是n+n-1+n-2+n-3....+3+2+1
n(n+1)/2
。现在你可以将它乘以得到n(n+1)/2 = n^2/2 + n/2
,在渐近运算中可以忽略常量,这意味着n^2/2 + n/2 = Theta(n^2+n)
,它也可以转换为n^2+n = Theta(n^2)
毕竟,结果没有改变,但你必须确定。
最终结果是n^3*log_2(n)
,如knightrider所述
答案 3 :(得分:1)
为了完整起见:在分析嵌套和共同依赖循环的时间复杂度时,例如在算法中,Sigma符号可以是一个很好的工具
其中⌊x⌋和⌈x⌉是floor and ceiling functions。
从上面可以看出,该算法的渐近行为的上限是O(n^3 log_2(n))
。
使用Sigma表示法估算实际迭代次数
Sigma符号分析除了是Big-O(-Ω,-Θ)分析的严格工具之外,如果我们对计算或估算实际迭代次数感兴趣还有用我们的算法。
我们比较估计的迭代次数 - 使用上面的≤符号之前的公式 - 与@JohnHascell:s答案中显示的实际迭代次数。
// our formula (pseudo-code / matlab-compliant)
numIt(n) = n*ceil(log2(n))*(n^2-n)/2;
// comparison with actual count:
---------------------------------------------------------
n actual # of iter. estimated # of iter.
(from @JohnHascell) (from formula above)
------------ ------------------- --------------------
1 0 0
10 1 800 1 800
100 3 465 000 3 465 000
1000 4 995 000 000 4 995 000 000
10000 6 999 300 000 000 6 999 300 000 000
---------------------------------------------------------
我们看到公式中的计数与实际计数完全一致;在这种情况下,估计实际上是实际计数。