我试图了解Big O符号到底是什么。通过在SO中回答类似问题的答案,我在字面和实践意义上理解它。但是答案没有解释,我不理解的是它背后的数学基础。 正式定义指出
A function T(n) is the Big-O notation of f(n), if and only if there exist two constants c, n0 > 0 such that
T(n) <= c * f(n) for all n >= n0.
我在某种程度上直观地理解这个方程试图用某个函数计算上界,这个函数在某种意义上具有更高的斜率,在函数f(n)的更高端。我知道我的理解是模糊的。那么有人可以解释Big-O表示法的数学基础/表示。
答案 0 :(得分:2)
首先我要说的是,如果 g(n)是 n 的函数,那么 O(g(n))是所有函数的集合 f(n)使得存在常数c,N> 0,使得对于所有n&gt; = N,f(n)&lt; = cg(n) /强>
如果分析一个算法完全,那么就会出现一个输入大小为 n 的函数,比如 f(n),这可能是 n 中的一些复杂烦人的多项式表达式(或涉及指数的复杂表达式)。
例如,有人可能会发现,给定输入大小 n 的算法具有 f(n)= 2n ^ 2 + 3n + 1 指令。 但我们并不关心 3n + 1 部分。如果 n 变得非常大,则 f 的 n ^ 2 项将支配低阶项。例如,对于 n = 100 ,我们已经发现 2 * 100 ^ 2 比 3 * 100 + 1 更重要。< / p>
所以,为了使这个想法更加严谨,我们想说“ f(n)在最坏的情况下增长,就像n ^ 2”。在数学符号中: f(n)是O(n ^ 2)的元素。现在你在问题中已经说过,要真正证明f(n)是O(n ^ 2)的元素,我们需要找到常数c和N,这样对于所有n&gt; = N我们都有f( n)&lt; = cn ^ 2。因此,如果我们尝试c = 3,那么我们得到不等式f(n)&lt; = 3 * n ^ 2,并且如果你以代数方式玩,那么你会发现对于所有n&gt; = 5这都成立。所以我们的c = 3,我们的N = 5。实际上,f(n)在最坏的情况下会像n ^ 2一样增长。
请注意,“最糟糕的是”。说“f(n)像......一样增长”,而不是我们说“ f(n)在最坏的情况下增长...”。< / p>
再举一个例子,再考虑我们的 f(n)= 2n ^ 2 + 3n + 1 。我的主张是 f(n)不是O(n)的元素。为了实际证明这是真的,我们需要表明,对于所有c,N> 0,存在n> = N,使得f(n)> 0。 CN。那么,f(n)>当且仅当2n ^ 2 +(3-c)n + 1> 1时,cn为真。 0,对于足够大的n> = N(无论N是多少)都是如此,我将让你详细说明。这表明 f(n)的增长率高于线性增长率。 p>
我们的 f(n)= 2n ^ 2 + 3n + 1 的另一个例子:可以证明f(n)是O(n ^ 3)的元素。我们这样做,好吗?我们需要找到c,N> 0,使得对于所有n> = N,f(n)<= cn ^ 3。好吧,试试c = 1;然后在一些代数之后,你会发现N = 4是正确的。这保证了“f(n)在最坏的情况下成长......就像......”的情绪;如果你能证明你的函数f在某个大O中,那么可能会有一个“更好的大O”,它就是它的一部分。
作为最后一个练习,显示O(1)是O(n)的正确的子集,它是O(n ^ 2)的正确的子集,这是O(n ^ 3)的正确的子集,它是O(n ^ 4)的正确的子集,...
答案 1 :(得分:1)
g(n)= O(f(n))表示在某个n之后(对于n> n0)g(n)/ f(n)<= M(固定量) 例如,对于n0 = 2,g(n)= n是O(n)和O(n * log(n)):
n / n = 1 <= 1 = M
n /(n * log(n))&lt; = 1 / log(2)= M