大O表示法 - 增长率

时间:2016-02-13 10:59:09

标签: algorithm big-o

我想知道我的推理是否正确:

如果我收到以下代码片段,并要求找到它的大O:

 for(int i = 3; i < 1000; i++)
    sum++;

我想说O(n),因为我们正在处理一个for循环和sum ++,迭代说n次然后看着这个我意识到我们根本没有处理n因为我们给了它多少次这个for循环迭代...但是在我看来,这有一个O(1)的大O是错误的,因为增长是线性的而不是常数并且取决于这个循环的大小(尽管循环是'不变')。我是否正确地说这是O(n)?

另外,让我思考的另一个有类似设置:

 for(int i = 0; i < n * n * n; i++)
    for(int j = 0; j < i; j++)
       sum++;

现在我再次知道,在处理包含外部和内部循环的嵌套循环时,我们将使用乘法规则来导出我们的Big O.假设内部循环实际上是j&lt;那么我会说这段代码的大O是O(n ^ 4)但是因为它不是,我们有一个第二个循环运行它的迭代i而不是n然后说这是正确的作为O(n ^ 3)的大订单?

我认为扔我的是'n'没有出现的地方,我们给了一个常数或另一个变量,突然之间我假设n不能考虑代码段。然而,说过我的推理的另一部分告诉我,尽管没有看到'n',我仍然应该对代码进行处理,好像有一个n,因为无论变量如何,增长率都是相同的?

3 个答案:

答案 0 :(得分:2)

如果您认为代码始终位于函数中,那么函数的参数用于计算复杂性,则效果最佳。因此:

// this is O(1), since it always takes the same time
void doSomething() {
    for(int i = 3; i < 1000; i++)
        sum++;
}

// this is O(n^6), since it only takes one argument
// and if you plot it, the curve matches t = k * n^6
void doSomethingElse(int n) {
  for(int i = 0; i < n * n * n; i++)
     for(int j = 0; j < i; j++)
        sum++;
}

最后,大O的重点是说运行时间(或记忆足迹;但如果你不说什么,你指的是运行时间看起来问题大小增加。重要的不是内部发生的事情(虽然你可以用它来估计复杂性) - 真正重要的是你在外面测量的东西。

仔细观察你的第二个片段,它是O(n ^ 6)因为:

  • 外循环恰好运行n ^ 3次;内循环平均运行n ^ 3/2次。
  • 因此,内部总和运行n ^ 3 * k * n ^ 3次(k为常数)。在big-O表示法中,那是O(n ^ 6)。

答案 1 :(得分:1)

第一个是 O(1)或者只是一个错误的问题,就像你理解它一样。

第二个是 O(n 6 。试着想象一下内环的大小。在第一次迭代时,它将是1.在第二次,2。在 i 上,它将是 i ,在最后一次,它将是 N * N * N 。所以它将是 n * n * n / 2 ,但那是 O(n * n * n)。那,外部 O(n 3 总计 O(n 6

答案 2 :(得分:1)

虽然其他人对你的问题的O()计算可能是正确的,但这里有一些更深入的见解,应该有助于描述整个渐近分析故事的概念前景。

  

我认为扔我的是哪里&#39; n&#39;没有出现,我们给了一个或另一个常数   变量,突然之间我不能考虑n   那部分代码。

理解这一个的最简单方法是确定一行代码的执行是否受n当前值的影响/相关。 如果有内环,那就说,j&lt; 10代替j&lt;我,复杂性很可能是O(n ^ 3)。

为什么任何常量被视为O(1)?

这可能听起来有点反直觉,但是,这是一个清晰的空气概念。 让我们说你的第一个循环运行1000次。然后你把它设置为10 ^ 1000次,并试着相信嘿,它不再需要相同的时间了。 很公平!即使它现在可能会使您的计算机运行相同的代码5秒钟,但时间复杂度仍然是O(1)。 这实际上意味着您实际上可以计算出计算机执行该段代码所需的时间,并且它将永远保持不变(对于相同的配置)。

Big-Oh实际上是输入上的功能,而不是离散值本身(时间/空间)的度量。

我希望上面的解释也有助于澄清为什么我们实际上忽略了O()表示法中的常量。

为什么这个大喔的事情如此普遍,为什么它首先被使用?

我想要包含这些额外信息,因为我在第一次学习这个主题时已经考虑到了这个问题。 渐近时间复杂度是对任何算法的先验分析,以理解该程序的最差(Big-Oh)行为(时间/空间),而不管输入的大小。 例如。你的第二个代码的表现不能比O(n ^ 6)差。 它是一般化的,因为从一台计算机到另一台计算机,只有不断的变化,而不是Big-Oh。

凭借更多的经验,您会意识到,实际上,您希望算法的时间复杂度尽可能地渐近变小。直到多项式函数,它很好。但是对于大输入,如果你试图运行具有O(k ^ n)或O(n ^ n)阶的指数时间复杂度的算法,今天的计算机就会开始咳嗽。旅行推销员和其他NP-C / H问题。

希望这会增加信息。 :)