我们的老师给了我们以下 Big O符号的定义:
O(f(n)): A function g(n) is in O(f(n)) (“big O of f(n)”) if there exist
constants c > 0 and N such that |g(n)| ≤ c |f(n)| for all n > N.
我试图梳理这个定义的各个组成部分。首先,我对g(n)在 O(f(n))中的含义感到困惑。 in 是什么意思?
接下来,我对声明的第二部分感到困惑。为什么说g(n)的绝对值小于或等于f(n)对于所有n> N表示 Big O Notation 的任何内容?
我对 Big O Notation 的一般直觉意味着它是一种描述算法运行时的方法。例如,如果在最坏的情况下冒泡排序在O(n ^ 2)中运行,这意味着它需要n ^ 2次操作的时间(在这种情况下是比较)来完成算法。我不明白这种直觉是如何从上面的定义中得出的。
答案 0 :(得分:0)
首先,我对g(n)在O(f(n))中意味着什么感到困惑。什么意思?
在此公式中,O(f(n))
是一组函数。因此O(N)
是所有函数的集合(简单来说)与N成比例,因为N倾向于无穷大。
“in”一词意味着......“是该集合的成员”。
为什么说g(n)的绝对值小于或等于f(n)对于所有n> N对Big O Notation有何意义?
定义。除此之外,你忽略了概要中的c
术语,这是定义的重要部分。
我对Big O Notation意味着什么的一般直觉是它是一种描述算法运行时的方法。例如,如果在最坏的情况下冒泡排序在O(n ^ 2)中运行,这意味着它需要n ^ 2次操作的时间(在这种情况下是比较)来完成算法。我不明白这种直觉是如何从上面的定义中得出的。
你的直觉在两个方面是不正确的。
首先,O(N^2)
的真正定义并非需要N^2
次操作。它是与 N^2
操作成比例的。这就是c
进入它的地方。
其次,对于N^2
足够大的值,它仅与N
成正比。关于小N
会发生什么的大O符号不。这是关于当问题规模扩大时会发生什么。
此外,作为评论说明“比例”在这里不是很正确的措辞。说“倾向于成比例”可能更为正确......但实际上并没有简单的英文描述这里发生了什么。真正的定义是数学定义。
如果您现在根据这一点重新阅读定义,您应该看到它非常适合。
(注意,Big O的定义和复杂性的相关度量也可以用微积分术语表示;即使用“限制”。但是,一般来说,我们所讨论的事情是量化的;即整数数字指令,整数个字节的存储等等。微积分实际上是关于涉及实数的函数。因此,你可以说上面的公式是优选的.OTOH,一个真正的数学家可能会在这个论证中看到总线大小的洞。)功能
答案 1 :(得分:0)
O(g(n))看起来像一个函数,但它实际上是一组函数。如果函数f在O(g(n))中,则意味着g是f的渐近上界,在常数因子内。 O(g(n))包含由g(n)从上面界定的所有函数。
更具体地,存在常数c和n0,使得f(n)<1。所有n的c * g(n)> N0。这意味着c * g(n)将总是超过f(n)超过n的某个值。 g渐近地大于f;它缩放得更快。这用于算法分析如下。算法的运行时间实际上无法指定。它显然取决于它运行的机器。我们需要一种谈论效率的方式,而不关心硬件问题。人们可能天真地建议计算算法执行的步骤并将其用作运行时间的度量,但这将取决于指定算法的粒度,因此也没有好处。相反,我们只关心运行时间(这个假设的事物T(n))与输入n的大小的缩放程度。
因此,我们可以通过以下方式报告运行时间:
我的算法(algo1)的运行时间T(n)在集合O(n ^ 2)中。即它从上面以n ^ 2的某个常数倍为界。
一些替代算法(algo2)可能具有O(n)的时间复杂度,我们称之为线性。对于某些特定的输入大小或某些硬件,这可能会或可能不会更好,但我们可以肯定地说:由于n倾向于无穷大,algo2将胜过algo1。
实际上,人们应该支持具有更好时间复杂度的算法,因为它们往往会运行得更快。
这种渐近符号也可以应用于内存使用。