这个求和算法的复杂性是多少?

时间:2014-02-01 14:27:57

标签: c algorithm

#include <stdio.h>

int main() {
    int N = 8;  /* for example */
    int sum = 0;
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= i*i; j++)
            sum++;

    printf("Sum = %d\n", sum);
    return 0;
}

对于每个n值(i变量),j值将为n ^ 2。所以复杂性将是n。 n ^ 2 = n ^ 3。这是对的吗?

如果问题变成:

#include <stdio.h>

int main() {
    int N = 8;  /* for example */
    int sum = 0;
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= i*i; j++)
            for (int k = 1; k <= j*j; k++)
                sum++;

    printf("Sum = %d\n", sum);
    return 0;
}

然后你使用现有的n ^ 3。 n ^ 2 = n ^ 5?这是对的吗?

6 个答案:

答案 0 :(得分:4)

我的点数为ij < i*ik < j*j x^1 * x^2 * (x^2)^2 = x^3 * x^4 = x^7

特别是,因为1 < i < N我们有i循环的O(N)。由于1 < j <= i^2 <= N^2我们有第二个循环的O(n ^ 2)。扩展逻辑,我们为第三个循环1 < k <= j^2 <= (i^2)^2 <= N^4

内部到外部循环,我们为每个N^4循环执行最多j次,每个N^2循环最多执行i次,最多{N次在i循环上1}}次,使得总数为N^4 * N^2 * N = N^7 = O(N^7)

答案 1 :(得分:1)

对于i = 1内循环运行1^1次,i = 2内循环运行2^2次......和i = N内循环运行{{ 1}}次。其复杂度为N^N的{​​{1}}。

在第二种情况下,对于1^1 + 2^2 + 3^3 + ...... + N^N,第一内循环迭代O(N^3)次,因此第二内循环(最内循环)将迭代最多i = N次。因此,复杂性为N^N,即N * (N^N) * (N^N)

答案 2 :(得分:1)

我认为复杂性实际上是O(n ^ 7)。

第一个循环执行N个步骤。 第二个循环执行N ^ 2步。

在第三个循环中,j * j可以达到N ^ 4,因此它具有O(N ^ 4)复杂度。

总的来说,N * N ^ 2 * N ^ 4 = O(N ^ 7)

答案 3 :(得分:0)

是。在第一个示例中,i循环运行N次,内部j循环调整i*i次,即O(N^2)。所以整件事是O(N^3)

在第二个示例中,还有一个额外的O(N^4)循环(循环到j*j),因此它总体上为O(N^5)

要获得更正式的证明,请计算sum++执行N次的次数,并查看N的最高多项式次序。在第一个示例中,它将是{{1 (对于a(N^3)+b(N^2)+c(N)+dabc的某些值,所以答案是3。

注意:编辑重新举例2说它是O(N ^ 4):d误读了i*i

答案 4 :(得分:0)

考虑所有循环的调用次数。

int main() {
int N = 8;  /* for example */
int sum = 0;
for (int i = 1; i <= N; i++)   /* Called N times */
    for (int j = 1; j <= i*i; j++) /* Called N*N times for i=0..N times */
        for (int k = 1; k <= j*j; k++) /* Called N^2*N^2 times for j=0..N^2 times and i=0..N times */ 
            sum++;

printf("Sum = %d\n", sum);
return 0;
}

因此sum ++语句被称为O(N ^ 4)* O(N ^ 2)* O(N)次= O(N ^ 7),这就是程序的整体复杂性。

答案 5 :(得分:0)

解决这个问题的不正确方法(虽然常见,并且经常给出正确答案)是近似内部循环的最大迭代次数与最坏情况。这里,内环在最坏的情况下循环O(N ^ 4),中间循环在最坏的情况下循环O(N ^ 2)次,外循环循环O(N)次,给出(偶然正确)O的解( N ^ 7)将它们相乘。

正确的方法是从内到外工作,小心谨慎地明确所接近的内容。

增量指令的总迭代次数T与您的代码相同。把它写出来:

T = sum(i=1..N)sum(j=1..i^2)sum(k=1..j^2)1.

最里面的总和只是j ^ 2,给出:

T = sum(i=1..N)sum(j=1..i^2)j^2

由j索引的总和是连续整数的平方和。我们可以精确计算:sum(j = 1..n)j ^ 2是n *(n + 1)*(2n + 1)/ 6。设置n = i ^ 2,我们得到

T = sum(i=1..N)i^2*(i^2+1)*(2i^2+1)/6

我们可以通过使用连续整数的6次,4次和2次幂的和的公式来继续计算确切的答案,但这是一种痛苦,而且对于复杂性我们只关心i的最高功率。所以我们可以近似。

T = sum(i=1..N)(i^6/3 + o(i^5))

我们现在可以使用该和(i = 1..N)i ^ p = Theta(N ^ {p + 1})来得到最终结果:

T = Theta(N^7)