算法的大O符号

Big O Notation for Algorithm

本文关键字:符号 算法      更新时间:2023-10-16

我正忙于做作业,正在为一个问题而挣扎。我知道我不应该直截了当地问作业问题,所以如果我没有得到直接的答案,我会理解的。但不管怎样,还是来了。

我们必须计算不同算法的运行时复杂性,我一直坚持的是这个。

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

现在,根据我的理解,我的第一个想法是小于O(n2),因为嵌套循环没有运行完整的n次,而且j变量在每个循环中递增2,而不是像循环的正常迭代那样迭代。尽管如此,当我用N=10、N=100、N=1000等进行一些代码模拟时,当我输出sum变量时,我得到了以下结果。

N = 10 : 25, 
N = 100 : 2500,
N = 1000 : 250000,
N = 10000 : 25000000

当我看到这些结果时,O符号似乎应该比O(n)大得多。

我们在赋值中给出的4个选项是:O(1),O(n2)、O(n)和O(logn)。正如我之前所说,我看不出它怎么会像O(n2)那么大,但结果表明了这一点。所以我只是觉得我没有完全理解这一点,或者我错过了一些环节。

任何帮助都将不胜感激!

Big O表示法不会给出操作数。它只是告诉你,随着投入的增加,它将以多快的速度增长。这就是你观察到的。

将输入c增加一倍后,操作总数将增加c^2

如果你精确地计算(几乎)精确的运算次数,你就会得到(n^2)/4

当然,你可以用总和来计算,但由于我不知道如何在SO上使用数学,我将给出一个"经验"解释。具有相同起始和结束条件的简单环中循环得到n^2。这样的循环产生"i""j"的所有可能组合的矩阵。因此,如果开始是1,结束是N,在这两种情况下,您都可以得到N*N组合(或有效的迭代)。

但是,您的内部循环适用于i < j。这基本上是由这个正方形形成一个三角形,这是第一个0.5因子,然后你跳过其他元素,这是另一个0.5因子;乘以1/4。

和CCD_ 13。有时人们喜欢把这个因素留在那里,因为它可以让你比较两种具有相同复杂性的算法。但它不改变相对于CCD_ 14的生长比率。

请记住,big-O是渐近表示法。常数(加法或乘法)对其影响为零。

因此,外循环运行n次,在第i次,内循环运行i / 2次。如果不是/ 2部分,它将是所有数字1 .. n的总和,也就是众所周知的n * (n + 1) / 2。对于非零的a,它扩展到a * n^2 + b * n + c,因此它是O(n^2)

我们不是对n数字求和,而是对n / 2数字求和。但这仍然在(n/2) * ((n/2) + 1) / 2附近。对于非零的d,它仍然扩展到d * n^2 + e * n + f,所以它仍然是O(n^2)

从您的输出中可以看到:sum~=(n^2)/4。

这显然是O(n^2)(实际上你可以用teta代替O)。您应该记得Big-O表示法的定义。看见http://en.wikipedia.org/wiki/Big_O_notation.

问题是,这里的运算次数取决于n的平方,尽管总数小于n²。然而,缩放对于Big-O表示法来说很重要,因此它是O(n²)

使用:

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

我们有:

0+2+4+6+...+2N == 2 * (0+1+2+3+...+N) == 2 * (N * (N+1) / 2) == N * (N+1)

因此,对于n == 2N,我们有(n / 2) * (n / 2 + 1)~=(n * n) / 4

所以O(n²)

您对时间复杂性的理解并不恰当。时间复杂性不仅仅是"answers"变量的问题sum只计算内部循环迭代的次数,但您还必须考虑外部循环迭代的总数。

现在考虑一下你的程序:

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

时间复杂性是指程序相对于输入值的运行时间(此处为n)。此处的运行时间并不意味着在计算机中执行程序所需的实际时间。实际所需时间因机器而异。因此,要获得独立于机器的运行时间,大O表示法非常有用。Bog O实际上来自数学,它用数学函数来描述运行时间。

外循环总共执行(n-1)次。对于这些(n-1个)值中的每一个(从i=1开始),内循环迭代i/2次。所以内循环迭代的总数=1+1+2+2+3++(n/2)+(n/2)=2(1+2+3+…+n/2)=2*(n/2(n/2+1))/2=n^2/4+n/2。类似地,"sum++"也执行了总共n^2/4+n/2次。现在考虑程序的第1行成本=c1,第2行成本=c2,第3行成本=c3。对于不同的机器,这些转换可能不同。因此执行程序所需的总时间=c1*(n-1)+c2*(n^2/4+n/2)+c3*(n^2/4+n/2。在大O表示法中,你可以说它是O(((c2+c3)n^2/4+(c2+c3)n/2+c1*n-c1)。在大O记法的情况下,可以忽略低阶项和最高阶项的系数。因为对于n的大值,n^2比n大得多,所以你可以说它是O((c1+c2)n^2/4)。同样对于n的任何值,n^2都比(c1+c2)n ^2/4大一个常数因子,所以你也可以说它为O(n^2)。