繁体   English   中英

大O符号-增长率

[英]Big O Notation - Growth Rate

我想了解我的推理是否正确:

如果我得到以下代码片段,并被要求查找它是Big 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++;

现在我再次知道,当处理包含内部和外部循环以及内部循环的嵌套循环时,我们将使用乘法规则来得出我们的BigO。让我们假设内部循环实际上是j <n,那么我会说Big O这段代码的代码是O(n ^ 4),但不是,我们有第二个循环在i而不是n上运行其迭代,那么将其称为O(n ^的大阶数)是正确的3)?

我认为让我感到困惑的是,没有出现“ n”的地方,并且给了我们一个常量或另一个变量,突然间,我假设那部分代码中不应考虑n。 但是,说完我的推理的另一部分是告诉我,尽管没有看到'n',但无论变量如何,增长率都一样,我还是应该将代码视为存在n呢?

如果您认为代码始终位于函数内,则该函数最好用函数的参数来计算复杂度。 从而:

// 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++;
}

最后,big-O的全部要点是要说明随着问题规模的增大 ,运行时间 (或内存占用量;但是如果您什么也没说,您是指运行时间)的样子 无关紧要的是内部发生了什么(尽管您可以使用它来估计复杂性)-真正重要的是您将在外部进行度量。

仔细查看您的第二个片段,它是O(n ^ 6),因为:

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

首先是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

尽管其他人对您的问题的O()的计算可能是正确的,但这里有一些更多的见识可以帮助您描述整个渐近分析故事的概念前景。

我认为让我感到困惑的是,没有出现“ n”的地方,并且给了我们一个常量或另一个变量,突然间,我假设那部分代码中不应考虑n。

理解这一点的最简单方法是确定一行代码的执行是否受n的当前值影响/与之相关。 假设内部循环是j <10而不是j <i,那么复杂度应该是O(n ^ 3)。

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

乍一看,这听起来似乎有点违反直觉,但是,这里有一个小的概念摘要可以使您大开眼界。 假设您的第一个循环运行了1000次。 然后将其设置为10 ^ 1000次,并尝试相信,不再需要相同的时间了。 很公平! 即使现在您的计算机可能需要5秒多的时间才能运行同一段代码,但时间复杂度仍为O(1)。 这实际上意味着您实际上可以计算计算机执行该代码段所花费的时间,并且该时间将永远保持不变(对于相同的配置)。

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

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

为什么Big-Oh这么泛化,为什么首先使用它?

我本来想包含这些额外的信息,因为我本人在初次学习该主题时就想到了这个问题。 渐近时间复杂度是对任何算法的先验分析,以了解该程序的最坏(Big-Oh)行为(时间/空间),而不管输入的大小如何。 例如。 您的第二个代码的性能不能比O(n ^ 6)差。 之所以这样概括是因为,从一台计算机到另一台计算机,只有不断变化,而不是Big-Oh。

有了更多的经验,您将意识到,实际上,您希望算法的时间复杂度尽可能地渐近变小。 直到多项式函数都可以。 但是对于大量输入,例如,如果您尝试以O(k ^ n)或O(n ^ n)的指数时间复杂度运行算法,今天的计算机就会开始咳嗽。 旅行商和其他NP-C / H问题。

希望这会增加信息。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM