【发布时间】:2010-11-24 18:24:32
【问题描述】:
Big-O 表示法O(n) 和Little-O 表示法o(n) 有什么区别?
【问题讨论】:
标签: algorithm time-complexity big-o asymptotic-complexity little-o
Big-O 表示法O(n) 和Little-O 表示法o(n) 有什么区别?
【问题讨论】:
标签: algorithm time-complexity big-o asymptotic-complexity little-o
f ∈ O(g) 说,本质上
对于至少一个常数k > 0的选择,你可以找到一个常数a使得不等式0 a。
请注意,O(g) 是满足此条件的所有函数的集合。
f ∈ o(g) 说,本质上
对于每一个选择一个常数k > 0,你可以找到一个常数a使得不等式0 a 成立。
再次注意,o(g) 是一个集合。
在 Big-O 中,您只需要找到一个特定的乘数 k,它的不等式超过某个最小值 x。
在 Little-o 中,一定有一个最小值 x,在这个最小值之后,无论你使 k 多么小,不等式都成立,只要它不是负数或零。
这两个都描述了上限,尽管有点违反直觉,Little-o 是更强的陈述。如果 f ∈ o(g) 与 f ∈ O(g) 相比,f 和 g 的增长率之间的差距要大得多。
差异的一个例子是:f ∈ O(f) 为真,但 f ∈ o(f) 为假。因此,Big-O 可以理解为“f ∈ O(g) 意味着 f 的渐近增长不快于 g's”,而“f ∈ o(g) 意味着 f 的渐近增长严格慢于 g's”。这就像 <= 与 <。
更具体地说,如果 g(x) 的值是 f(x) 值的常数倍,则 f ∈ O(g) 为真。这就是为什么在使用 big-O 表示法时可以删除常量的原因。
但是,如果 f ∈ o(g) 为真,那么 g 必须在其公式中包含 x 的更高幂,因此 f(x) 和 g(x) 之间的相对分离) 实际上必须随着 x 变大而变大。
使用纯数学示例(而不是指算法):
以下适用于 Big-O,但如果使用 little-o,则不适用:
以下情况适用于 little-o:
请注意,如果 f ∈ o(g),这意味着 f ∈ O(g)。例如x² ∈ o(x³) 所以 x² ∈ O(x³) 也是正确的,(再次,将 O 视为<=,将 o 视为<)
【讨论】:
a 有一个 k 那个:...”,而是“对于每个 k 有一个 a 这个:...”
Big-O 之于 little-o 就像 ≤ 之于 <。 Big-O 是一个包容性的上限,而 little-o 是一个严格的上限。
例如函数f(n) = 3n是:
O(n²)、o(n²) 和O(n)
O(lg n)、o(lg n) 或o(n) 中
类似地,数字1是:
≤ 2、< 2 和 ≤ 1
≤ 0、< 0 或< 1
这是一个表格,显示了总体思路:
(注意:该表是一个很好的指南,但它的限制定义应该根据superior limit 而不是正常限制。例如,3 + (n mod 2) 永远在 3 和 4 之间波动。尽管它在O(1)没有正常限制,因为它仍然有一个lim sup: 4。)
我建议记住 Big-O 表示法如何转换为渐近比较。比较更容易记住,但不够灵活,因为你不能说 nO(1) = P.
【讨论】:
我发现当我无法从概念上掌握某件事时,思考为什么要使用 X 有助于理解 X。(不是说你没有尝试过,我只是设置舞台。)
你知道的东西:对算法进行分类的一种常用方法是按运行时间,通过引用算法的大复杂度,你可以很好地估计哪个算法“更好” -- 以 O! 中具有“最小”功能的为准即使在现实世界中,O(N) 也比 O(N²)“更好”,除非是诸如超大质量常数之类的傻事。
假设有一些算法在 O(N) 中运行。很不错吧?但是假设你(你聪明的人,你)想出了一个运行在 O(N⁄loglogloglogN) 的算法。耶!它更快!但是当你写论文的时候,你会觉得一遍又一遍地写这个很傻。所以你写一次,你可以说“在这篇论文中,我已经证明了算法 X,以前可以在 O(N) 时间内计算,实际上可以在 o(n) 时间内计算。”
因此,每个人都知道您的算法更快 --- 多少不清楚,但他们知道它更快。理论上。 :)
【讨论】:
渐近符号可以理解为:缩小时函数如何比较?(测试这一点的一个好方法是使用Desmos 之类的工具并使用鼠标滚轮进行操作)。特别是:
f(n) ∈ o(n) 的意思是:在某些时候,你越缩小,f(n) 将被n 支配(它会逐渐偏离它)。g(n) ∈ Θ(n) 表示:在某些时候,缩小不会改变 g(n) 与 n 的比较(如果我们从轴上移除刻度,您将无法判断缩放级别)。最后h(n) ∈ O(n) 表示函数h 可以属于这两个类别中的任何一个。它可能看起来很像n,或者当n 增加时,它可能比n 越来越小。基本上f(n)和g(n)都在O(n)中。
我认为这个维恩图(来自this course)可能会有所帮助:
在计算机科学中,人们通常会证明给定算法同时接受上限O 和下限?。当两个界限都满足时,这意味着我们找到了一种渐近最优算法来解决该特定问题Θ。
例如,如果我们证明算法的复杂度在O(n) 和?(n) 中,则意味着它的复杂度在Θ(n) 中。 (这是Θ 的定义,它或多或少地转换为“渐近相等”。)这也意味着没有算法可以解决o(n) 中的给定问题。再次粗略地说“这个问题不能(严格)少于n个步骤来解决”。
通常在下限证明中使用o 来显示矛盾。例如:
假设算法
A可以在o(n)步骤中找到大小为n的数组中的最小值。由于A ∈ o(n)它无法从输入中看到所有项目。换句话说,至少有一项xA从未见过。算法A无法区分两个相似输入实例之间的区别,其中只有x的值发生变化。如果x是其中一个实例中的最小值,而不是另一个实例中的最小值,则A将无法找到(至少)这些实例之一中的最小值。也就是说,在数组中求最小值在?(n)中(o(n)中没有算法可以解决这个问题)。
O(n) 的上限仅仅意味着即使在最坏的情况下,算法也将在最多n 步中终止(忽略所有常数因子,包括乘法和加法)。 ?(n) 的下限是关于问题本身的陈述,它表示我们构建了一些示例,其中给定的问题任何算法都无法在少于 n 的步骤中解决(忽略乘法和加法常数)。步数最多是n,至少是n,所以这个问题的复杂度是“正好n”。而不是每次我们只写Θ(n)时都说“忽略常数乘法/加法因子”。
【讨论】:
big-O 表示法有一个称为 small-o 表示法的伴侣。大 O 表示法表示一个函数是渐近的 no more than 另一个。要说一个函数是渐近的 less than 另一个函数,我们使用 small-o 表示法。 big-O 和 small-o 符号之间的区别类似于
【讨论】: