Math 查找算法的计算复杂性
算法:Math 查找算法的计算复杂性,math,optimization,computer-science,big-o,Math,Optimization,Computer Science,Big O,算法: for (int i = 0; i < 2*n; i += 2) for (int j = n; j >i; j--) foo(); 我已经做了所有的工作,但我的方程式总是给出有点偏离的值: 当n=5时:录制的foo()调用是9,但我的等式是6。 当n=6时:录制的foo()调用是16,但我的等式是9 我做错了什么?有时候经验方法很有效。看 #包括 整数计数(整数n){ int i,j,乘以=0; 对于(i=0;ii;j--) 时代++; 返
for (int i = 0; i < 2*n; i += 2)
for (int j = n; j >i; j--)
foo();
我已经做了所有的工作,但我的方程式总是给出有点偏离的值:
当n=5时:录制的foo()调用是9,但我的等式是6。当n=6时:录制的foo()调用是16,但我的等式是9
我做错了什么?有时候经验方法很有效。看
#包括
整数计数(整数n){
int i,j,乘以=0;
对于(i=0;i<2*n;i+=2)
对于(j=n;j>i;j--)
时代++;
返回次数;
}
int main(){
int i;
对于(i=0;i<20;i++)
printf(“%2d%10d\n”,i,计数(i));
返回0;
}
0 0
1 1
2 2
3 4
4 6
5 9
6 12
7 16
8 20
9 25
10 30
11 36
12 42
13 49
14 56
15 64
16 72
17 81
18 90
19 100
查看输出,您可以从T(n-1)、T(n-2)等生成T(n)的方式进行推断,并且可以编写T的递归定义。这似乎是您所采用的方法
通过尝试直接从输出中找出模式,您可能能够更快地获得一个封闭的模式。例如,我们从输出中看到:
- 当n为奇数时,T(n)为ceil(n/2)**2
- 当n为偶数时,T(n)为(n/2)*(n/2+1)
这表明T(n)渐近收敛到n^2/4。这与你得到的答案一致。也许你是说你的结果“有点不对劲”,因为对于较小的n值,你看不到确切的n^2/4。这很好。重要的是,在极限情况下,复杂性为n^2/4。当然,你也可以说θ(n^2)…总和有n/2+1项;i=0是第一项,i=n/2是最后一项 所以你应该有 总和(n)=(n/2+1)(n+n)/2 及
求和(f(x))=(n/2+1)(0+n)/2。算法有道理,无法理解您的结果,请发布与您期望的结果不起作用的代码奇数应该是
(n+1)^2/4
,偶数应该是n/2*(n/2+1)
。我所做的是使函数foo递增一个“ActualCount”整数。然后我将实际计数与复杂度方程n^2/4生成的结果进行比较。对于n=5的情况,实际计数是9,而我的等式是6;我明白了。不过,感谢您提出的替代方法建议,我会看看是否更喜欢它=)
# of foo() calls for the second loop as i changes:
1st loop: n - 0
2nd loop: n - 2
3rd loop: n - 4
nth loop: n - f(x); f(x) = last term +2; where f(0) = 0
Total # calls = Summation(n - f(x)) from [i = 0] to [i = n/2 (where f(x) == n)]
= Summation(n) - summation(f(x))
= (n/2)(n+n)/2 - (n/2)(0 + n)/2
= n^2/2 - n^2/4
= n^2/4
#include <stdio.h>
int count(int n) {
int i, j, times = 0;
for (i = 0; i < 2 * n; i += 2)
for (j = n; j > i; j--)
times++;
return times;
}
int main() {
int i;
for (i = 0; i < 20; i++)
printf("%2d%10d\n", i, count(i));
return 0;
}
0 0
1 1
2 2
3 4
4 6
5 9
6 12
7 16
8 20
9 25
10 30
11 36
12 42
13 49
14 56
15 64
16 72
17 81
18 90
19 100