【问题标题】:Need help finding the complexity of this algorithm需要帮助找出该算法的复杂性
【发布时间】:2014-02-24 03:15:53
【问题描述】:

您好,我需要帮助找出该算法的复杂性。 您能否逐行回答复杂性,而不仅仅是最终结果?

算法如下:

int algorithm(int x)
{
    int y = 1;
    while (y <= x-1)
    {
        int z = y*2;
        while (z <= x)
        {
            int w = 1;
            while (w <= z)
            {
                w++;
            }
            z++;
        }
        y++;
    }
}

任何帮助将不胜感激!

谢谢

【问题讨论】:

  • 听起来有点像“你能帮我做作业吗”。你对复杂性了解多少?你觉得这段代码有什么困难?
  • 并不是我只是想自己学习一些复杂性。到目前为止,我知道如何找到第一个循环的复杂性,但我不知道如何找到第一个循环内循环的复杂性。
  • 好的;第一个(最外层)循环的复杂性是多少?如果您忽略了两个外部循环,那么第三个(最里面的)循环的复杂度是多少?如果忽略最内层循环的复杂度,那么中间循环的复杂度是多少?所以,你现在有了 3 个循环的结果——复合有多复杂?

标签: c algorithm complexity-theory time-complexity code-complexity


【解决方案1】:
int algorithm(int x)
{
    int y = 1;
    while (y <= x-1)    // <<< loop 1
    {
        int z = y*2;
        while (z <= x)  // <<< loop 2
            int w = 1;
            while (w <= z) // <<< loop 3
            {
                w++;
            }
            z++;
        }
        y++;
    }
}

让我们分解一下。

循环 1:绕 (x-1) 次:我们称之为 O(x)。很简单。

循环 2:我们从 2*y 开始 Z,所以 2, 4, 6, ... 从那里一直到 x。让我们把它们加起来:

sum((x-2) + (x-4) + (x-6) + ... + (x - x)) =
x * x / 2 - 2 * (1+2+3+...+x/2) =
x * x / 2 - 2 * (x/2)*(x/2+1) / 2 ~
x * x / 2 - x * x / 4 =
x * x / 4
= O(x^2)

现在是最里面的循环:它从w = 1w = z;所以它循环z 次。我们知道

z = 2, 4, 6, ... x

所以最里面的循环添加了 x 顺序的东西(x/2...同样的东西)。

结合循环 3 的 O(x) 和循环 2 的 O(x^2)(包括第一个循环的效果),我们得出结论“算法”的顺序为 x^3。为了验证,我们可以修改您的代码:

#include <stdio.h>

int algorithm(int x)
{
    int c = 0;
    int y = 1;
    while (y <= x-1)
    {
        int z = y*2;
        while (z <= x)
        {
            int w = 1;
            while (w <= z)
            {
                c++; // count complexity
                w++;
            }
            z++;
        }
        y++;
    }
    return c;
}

int main(void) {
    int ii;
    for(ii = 200; ii <= 400; ii+=10) {
      printf("%d   %d\n", ii, algorithm(ii));
    }
}

输出是:

200   1338350
210   1549030
220   1780735
230   2034465
240   2311220
250   2612000
260   2937805
270   3289635
280   3668490
290   4075370
300   4511275
310   4977205
320   5474160
330   6003140
340   6565145
350   7161175
360   7792230
370   8459310
380   9163415
390   9905545
400   10686700

将其绘制在 lin-log 图上,您会得到一条非常直线。

当你取algorithm(400) / algorithm(300) 的比率时,你得到 2.369。而当你选择(400/300)^3,答案就是2.370。我认为这足以令人信服。

【讨论】:

    【解决方案2】:

    按照下面的正式步骤(希望您对 Sigma 表示法感到满意),您将能够获得算法的确切增长顺序:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多