Function(int n)
if(n<=2)
return 1;
for(i=n ; i>n/8 ; i-=n/2)
for(j=n ; j>2 ; j=j/2)
syso();
return Function(n/2);
为了进行计算,我做了以下工作: T(n)= T(n / 2) + O(1)+ 2logn
**我假设第二个for循环会将j除以2,这意味着我将有j / 2 ^ k次迭代= logn。
使用相同的逻辑进行下一步: T(n)= (T(n / 2 ^ 2)+ O(1)+ 2logN) + O(1)+ 2logn 继续直到K步: T(n)= T(n / 2 ^ k)+ O(1)+ 2 * klogn
从第一个“ if”语句开始,函数将在n <= 2时停止,因此:
n / 2 ^ k =? 2> k = log(n)-1。
现在我将k放入函数中,我得到: T(n)= T(2)+ O(1)+ 2(logn)^ 2-2logn 我们知道T(2)= O(1),因为它只是在执行“ if”语句。
T(n)= O(1)+ 2(logn)^ 2-2logn。 假设我完成的所有步骤都正确,那么复杂度是否为O((logn)^ 2)?
或者我的计算有误。
答案 0 :(得分:0)
您可以使用一个示例程序来计算n
的各种值调用内部循环的次数。运行下面的程序,看起来复杂度是〜2*log(n)^2
。
package example;
public class Example1 {
public static void main(String[] args) {
int c=4;
for (int i=0;i<20;i++) {
new FunctionOpsCount(c).dump();
c=c*2;
}
}
}
class FunctionOpsCount {
int ops;
private int n_;
FunctionOpsCount (int n) {
this.n_=n;
f(n);
}
private int f(int n) {
if(n<=2)
return 1;
for(int i=n ; i>n/8 ; i-=n/2)
for(int j=n ; j>2 ; j=j/2)
incrementOp();
return f(n/2);
}
private void incrementOp() {
ops++;
}
void dump() {
System.out.printf("n=%d ops=%d 2*log(n)^2/ops=%f%n", n_, ops, 2.*Math.log(n_)*Math.log(n_)/ops);
}
}
它会打印:
n=4 ops=2 2*log(n)^2/ops=1,921812
n=8 ops=6 2*log(n)^2/ops=1,441359
n=16 ops=12 2*log(n)^2/ops=1,281208
n=32 ops=20 2*log(n)^2/ops=1,201133
n=64 ops=30 2*log(n)^2/ops=1,153087
n=128 ops=42 2*log(n)^2/ops=1,121057
n=256 ops=56 2*log(n)^2/ops=1,098178
n=512 ops=72 2*log(n)^2/ops=1,081019
n=1024 ops=90 2*log(n)^2/ops=1,067673
n=2048 ops=110 2*log(n)^2/ops=1,056997
n=4096 ops=132 2*log(n)^2/ops=1,048261
n=8192 ops=156 2*log(n)^2/ops=1,040982
n=16384 ops=182 2*log(n)^2/ops=1,034822
n=32768 ops=210 2*log(n)^2/ops=1,029542
n=65536 ops=240 2*log(n)^2/ops=1,024966
n=131072 ops=272 2*log(n)^2/ops=1,020963
n=262144 ops=306 2*log(n)^2/ops=1,017430
n=524288 ops=342 2*log(n)^2/ops=1,014290
n=1048576 ops=380 2*log(n)^2/ops=1,011480
n=2097152 ops=420 2*log(n)^2/ops=1,008951
答案 1 :(得分:0)