Θ(n)和O(n)有什么区别?


427

有时我看到Θ(n)带有一个奇怪的Θ符号,中间带有一些符号,有时只是O(n)。仅仅是因为没有人知道如何键入此符号而使输入变得懒惰,还是意味着有所不同?


8
这不是很明显,但是这个问题与昨天的这个stackoverflow.com/questions/464078/…重复。
比尔蜥蜴,

Answers:


600

简短说明:

如果算法为Θ(g(n)),则意味着随着n(输入大小)变大,算法的运行时间与g(n)成比例。

如果算法为O(g(n)),则意味着随着n变大,算法的运行时间最多与g(n)成比例。

通常,即使当人们谈论O(g(n))时,它们的实际含义是Θ(g(n)),但从技术上讲,还是有区别的。


从技术上讲:

O(n)表示上限。Θ(n)表示紧密边界。Ω(n)表示下限。

f(x)=Θ(g(x))iff f(x)= O(g(x))和f(x)=Ω(g(x))

基本上,当我们说一个算法为O(n)时,它也是O(n 2),O(n 1000000),O(2 n),...但Θ(n)算法不是 Θ(n 2) 。

实际上,由于f(n)=Θ(g(n))意味着具有足够大的n 值,因此对于某些c值,f(n)可以绑定在c 1 g(n)和c 2 g(n)内1和c 2,即f的生长速率是渐近等于克:克可下限和上结合的F。这直接暗示f也可以是g的下限和上限。所以,

f(x)=Θ(g(x))如果g(x)=Θ(f(x))

类似地,要显示f(n)=Θ(g(n)),足以表明g是f的上限(即f(n)= O(g(n))),而f是f的下限g(即f(n)=Ω(g(n)),与g(n)= O(f(n))完全相同)。简而言之,

f(x)=Θ(g(x)),如果f(x)= O(g(x))和g(x)= O(f(x))


也有little-oh和little-omega(ω)表示法表示函数的上限和下限。

总结一下:

f(x) = O(g(x))(big-oh)表示的增长率f(x)渐近小于或等于的增长率g(x)

f(x) = Ω(g(x))(大欧米茄)表示的增长率f(x)渐近大于或等于的增长率g(x)

f(x) = o(g(x))(小哦)表示的增长率f(x)是渐近的小于的增长率g(x)

f(x) = ω(g(x))(小欧米茄)表示的增长率f(x)渐近大于的增长率。g(x)

f(x) = Θ(g(x))(theta)表示的增长率f(x)渐近等于的增长率g(x)

有关更详细的讨论,您可以阅读Wikipedia上的定义,也可以参考经典的教科书,例如Cormen等人的《算法简介》。


1
如果“如果算法为O(g(n)),则意味着随着n变大,算法的运行时间最多与g(n)成比例。” 那你怎么说“基本上说一个算法是O(n),它也是O(n2),O(n1000000),O(2n)”?
Andy897

@ Andy897它来自“比例”的定义。摘自Wikipedia:“在数学中,如果一个变量的变化总是伴随另一个变量的变化,并且如果这些变化总是通过使用常数乘数进行关联,则两个变量是成比例的。该常数称为比例系数或比例系数不变。”
Mehrdad Afshari

什么>= \Omega(...)意思 我知道我们是否说它是的成员\Omega(...),但是否大于它?这有什么意义?
Johannes Schaub-litb

328

有一种简单的方法(我猜是一种技巧)可以记住哪种表示法意味着什么。

所有的Big-O标记都可以视为带有竖线。

当查看Ω时,条形图在底部,因此它是一个(渐近的)下界。

当查看Θ时,条显然在中间。所以这是一个(渐近的)紧边界。

手写O时,通常在顶部完成,然后绘制花样。因此,O(n)是函数的上限。公平地说,这种字体不适用于大多数字体,但这是名称的原始证明。


5
对于任何问题,我通常都不会低于3-4个答案。这值得一游。感谢您分享技巧。:D
不可能的

56

一个是大“ O”

一个是大Theta

http://en.wikipedia.org/wiki/Big_O_notation

大O表示您的算法将不超过给定表达式(n ^ 2)的步骤执行

大欧米茄(Omega)意味着您的算法将以比给定表达式(n ^ 2)更少的步骤执行

当两个条件对于同一个表达式都成立时,可以使用大theta表示法...。


20
但是是错的!当n变得非常大时,步数受n ^ 2限制。但是,以n ^ 2 + c步长运行的算法要花费n ^ 2步以上,但仍然是O(n ^ 2)。Big-O符号仅描述渐近行为。
2009年

1
这不是最终的全部定义。这只是一个起点。...由于我们正在谈论随着n接近无穷大的渐近符号。常数C成为非因数。
l_39217_l

1
虽然我喜欢这个答案的简单性,但应注意,O(n ^ 2)算法可以很好地执行1,000,000,000 * n ^ 2个步骤来执行,这肯定比n ^ 2大得多。算法为O(n ^ 2)只是意味着将执行不超过k * n ^ 2个步骤,其中k是某个正实数。
MarredCheese

38

我将提供一个简单的示例,而不是提供已经在此处进行了漂亮总结的理论定义:

假设运行时间f(i)O(1)。以下是一个代码片段,其渐近运行时为Θ(n)。它总是调用函数f(...) n时间。上下限均为n。

for(int i=0; i<n; i++){
    f(i);
}

下面的第二个代码片段的渐近运行时为O(n)。它f(...) 在大多数 n时候调用该函数。上限为n,但下限可以为Ω(1)Ω(log(n)),具体取决于内部发生的情况f2(i)

for(int i=0; i<n; i++){
    if( f2(i) ) break;
    f(i);
}

“渐近运行时”是什么意思?
菜刀lion4

1
在这种情况下,渐近意味着“足够大的n”。渐近运行时间Θ(n)为n 的代码片段的运行时间将线性增长,例如,运行时间T可表示为T(n)= a * n + b。对于较小的n值(例如n = 1或2),这可能不是描述行为的最佳方法-也许您有一些初始化代码花费的时间比f(i)长得多。
kara deniz 2014年

11

Theta是指特殊情景的一种简写方式,其中O和Omega相同。

因此,如果有一个主张The Theta is expression q,那么他们也必然要求Big O is expression qOmega is expression q


粗略类推:

如果:Theta声称“那只动物有5条腿”。然后得出结论:大O为真(“该动物的腿小于或等于5条腿。”),欧米茄为真(“该动物的腿大于或等于5条腿。”)

这只是一个粗略的类比,因为表达式不一定是特定的数字,而是各种数量级的函数,例如log(n),n,n ^ 2等。


11

可以使以前的答案更容易理解:

Θ符号-相同顺序| O标记-上限

Θ(n)-相同的阶数 O(n)-上限

用英语,

在左侧,请注意,存在一个上限和下限,它们都具有相同的数量级(即g(n))。忽略常数,并且如果上限和下限具有相同的数量级,则可以有效地说f(n)=Θ(g(n))f(n)处于g(n)的大theta中

从右边开始,这是更简单的示例,它说上限g(n)只是数量级,并且忽略了常数c(就像所有大O表示法一样)。


您弄乱了单词和图表。
kushalvm

@kushalvm,感谢您的诚实。您能具体解释一下什么意思吗?为了我和其他人的学习,可能对此答案感到困惑。:-)
里卡多

最后一段的最后一行不应该是f(n)是g(n)的Theta吗?
kushalvm '18

@kushalvm,谢谢您的澄清。我更改了段落最后一行之前的最后一行的文本,以解决我的英语错误。
里卡多

进一步了解发音
Ricardo


3

使用限制

让我们考虑f(n) > 0g(n) > 0所有n。可以考虑一下,因为最快的实算法至少有一个操作并在启动后完成其执行。这将简化演算,因为我们可以使用值(f(n))代替绝对值(|f(n)|)。

  1. f(n) = O(g(n))

    一般:

              f(n)     
    0 ≤ lim ──────── < ∞
        n➜∞   g(n)
    

    对于g(n) = n

              f(n)     
    0 ≤ lim ──────── < ∞
        n➜∞    n
    

    例子:

        Expression               Value of the limit
    ------------------------------------------------
    n        = O(n)                      1
    1/2*n    = O(n)                     1/2
    2*n      = O(n)                      2
    n+log(n) = O(n)                      1
    n        = O(n*log(n))               0
    n        = O(n²)                     0
    n        = O(nⁿ)                     0
    

    反例:

        Expression                Value of the limit
    -------------------------------------------------
    n        ≠ O(log(n))                 ∞
    1/2*n    ≠ O(sqrt(n))                ∞
    2*n      ≠ O(1)                      ∞
    n+log(n) ≠ O(log(n))                 ∞
    
  2. f(n) = Θ(g(n))

    一般:

              f(n)     
    0 < lim ──────── < ∞
        n➜∞   g(n)
    

    对于g(n) = n

              f(n)     
    0 < lim ──────── < ∞
        n➜∞    n
    

    例子:

        Expression               Value of the limit
    ------------------------------------------------
    n        = Θ(n)                      1
    1/2*n    = Θ(n)                     1/2
    2*n      = Θ(n)                      2
    n+log(n) = Θ(n)                      1
    

    反例:

        Expression                Value of the limit
    -------------------------------------------------
    n        ≠ Θ(log(n))                 ∞
    1/2*n    ≠ Θ(sqrt(n))                ∞
    2*n      ≠ Θ(1)                      ∞
    n+log(n) ≠ Θ(log(n))                 ∞
    n        ≠ Θ(n*log(n))               0
    n        ≠ Θ(n²)                     0
    n        ≠ Θ(nⁿ)                     0
    

2

结论:我们将大O,大θ和大Ω视为同一事物。

为什么?我将在下面说明原因:

首先,我要澄清一个错误的说法,有人认为我们只关心最差的时间复杂度,因此我们总是使用大O而不是大θ。我会说这个人在胡说八道。上限和下限用于描述一个功能,而不用于描述时间复杂度。最差时间函数具有上限和下限;最佳时间函数也有其上限和下限。

为了清楚地解释大O和大θ的关系,我将首先解释大O和小O的关系。根据定义,我们很容易知道小o是大O的子集。例如:

T(n)= n ^ 2 + n,我们可以说T(n)= O(n ^ 2),T(n)= O(n ^ 3),T(n)= O(n ^ 4)。但是对于小o,T(n)= o(n ^ 2)不满足小o的定义。因此,对于小o,仅T(n)= o(n ^ 3),T(n)= o(n ^ 4)是正确的。冗余T(n)= O(n ^ 2)是什么?θ大!

通常,我们说大O是O(n ^ 2),很难说T(n)= O(n ^ 3),T(n)= O(n ^ 4)。为什么?因为我们在潜意识里把大O当作大θ。

同样,我们也下意识地将大Ω视为大θ。

一言以蔽之,大O,大θ和大Ω从定义上不是同一回事,但在我们的嘴和大脑中它们是同一回事。


为什么将这些内容格式化为引号?它从外部源报价?如果是这样,则应链接来源或以其他方式标识来源。如果不是,应删除引号格式。
Mark Amery
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.