O(·)不是一个函数,那么一个函数如何等于它呢?


47

我完全理解大O符号的含义。我的问题是,当我们说T(n)=O(f(n)),其中T(n)是大小为n输入上算法的运行时间。

我了解它的语义。但是T(n)和O(f(n))是两回事。

T(n)是一个精确的数字,但是O(f(n))不是一个产生数字的函数,因此从技术上讲我们不能说T(n) 等于 O(f(n))。您 O (f (n ()))的值是多少,答案是什么?没有答案。O(f(n))


7
简单地说,T(n)=O(f(n))中的=符号并不意味着“等于”。问题在于这个假设。您是否找到了这样的消息来源?
— ShreevatsaR

20
这只是滥用数学符号的多种方式之一:(
— Technical_difficulty

13
如果数字是64,我怎么能成为64?
— TaW

7
Wikipedia始终是一个开始寻找答案的好地方-它有一个部分讨论这一确切点。
— 迪克林18/12/12

3
@mathreadler没有算法。认为big-O在谈论一种算法,就像认为十进制在谈论某人的身高。big-O是谈论数学函数增长率的一种表示法;十进制是数字的符号。数学函数可以是(但不是必须)某种算法的运行时间。这个数字可以是但不一定是某人的身高。
— David Richerby

Answers:


107

严格来说,O(f(n))是一组函数。因此O(f(n))值只是所有函数的集合,这些函数渐近地增长的速度不快于f(n)。符号T(n)=O(f(n))仅仅是写入一个常规方式T(n)∈O(f(n))。

请注意,这也阐明了O表示法的一些注意事项。例如,我们写(1/2)n2+n=O(n2),但我们从未写O(n2)=(1/2)n2+n。引用Donald Knuth(计算机编程艺术,1.2.11.1):

最重要的考虑是单向平等的思想。[...]如果α(n)和是涉及符号的公式,则符号表示由被包含在由表示的组。β(n)Oα(n)=β(n)α(n)β (Ñ )β(n)


3
我不明白第二段。我认为,当我们写,我们的意思是˚F ∈ Ø(˚F (ñ ))。但不应ø(˚F (Ñ ))= Ö(克(Ñ ))被解释为集平等,由于Ö(˚F (Ñ ))∈ Ô(克(Ñ ))f=O(f(n))f∈O(f(n))O(f(n))=O(g(n))O(f(n))∈O(g(n))没有任何意义(这是类型错误!)。如果是这样,为什么这么说呢 ,但Ø(ñ 3)∉ Ø(ñ 2)在第二段落?O(n2)∈O(n3)O(n3)∉O(n2)
— Alex Vong

7
因为当同时设置我们把它解释为O(n2)⊂O(n3)
— RIAD

1
我会在实际需要的地方使用文字。在计算中,您通常只需要一面东西
— RiaD

11
我从未见过任何文字或其他严肃来源中的O(n ^ 2)= O(n ^ 3)。你能举一个吗?
— Yakk

1
如果我们要更加严格,和ñ 3不是函数,˚F和ñ ↦ ñ 3是。但是,“由于某种原因,”我还没有看到任何人写ñ ↦ ň 2 ∈ Ø(ñ ↦ ñ 3)中,是为了被人们所阅读文本。f(n)n3fn↦n3n↦n2∈O(n↦n3)
— JiK

43

O是一个函数

O:(N→R)→P(N→R)f↦O(f)
,即它接受一个函数f并产生一组共享的结合(至多)的渐近函数f。而且严格来说正确的符号是这样
(n↦T(n))∈O(n↦f(n))
或短
T∈O(f)
,但它在数学,科学和CS习惯上只使用一个变量的地方该表达式表示您正在考虑参数n的函数n双方。所以T(n)∈O(f(n))是相当精细,以及。正如您所怀疑的,T(n)=O(f(n))几乎是错误的。尽管它是非常常用的,所以一定要记住人们在写这篇文章时的意思。

我建议不要写T(n)=O(f(n)),但是意见不一。


11
是符号的完全标准用法,因此断言错误是无济于事的(正如IMO声称 O是一个函数;从技术上讲这是正确的,但实际上并不是一种有用的方法考虑一下。)T(n)=O(f(n)O
— David Richerby

38
@DavidRicherby有些事情是完全标准的,但不应该如此。是一个例子。当然,了解人们的含义还是很不错的(正如OP所做的那样),但是确认此表示从技术上讲是虚假的,这对我们没有帮助吗?你为什么要使用它?即使=版本一点也不含糊,无论是∈之一,而更多的人切换到符号越好。始终坚持在数学上真正有意义的东西总是更好,除非编写起来更加尴尬。∈T(n)=O(f(n))=∈∈完全可读且易于编写。
— 左右大约

1
@leftaroundabout当您说“除非要写得多笨拙”时,您已将手指放在上面—使用的确确实要笨拙得多,除非在特殊情况下,LHS上没有O ()项恰好是RHS上的一个。(例如,请参见像这样的渐近方法,将其与我的答案进行比较,并将其与放弃O()表示法的所有优点并必须依靠不合理的假设的答案进行比较。)表示法的目的是帮助思考,并且有通过更改“ =”的含义可以在这里获得更多收益∈O()
— ShreevatsaR

2
@ShreevatsaR不知道你要去哪里。我还没有非常仔细地阅读过链接文章,但是TBH那里的文章似乎最令人费解,并且需要一大堆(有点晦涩,“现在无法在书中找到”)规则,而其他答案很容易从第一原则给出解决方案。反正什么阻止你刚刚更换“被虐” 有迹象∈和⊂为合适?=∈⊂
— 大约

1
@ShreevatsaR我同意建立一套规则/定理是理论的重点。但是最重​​要的是在适用时明确为每条规则进行形式化。IMO类型理论是最好的框架,但是在实践中,幼稚的集合已经足够接近了。但是,涉及 / o / Θ符号的代数表达式的幼稚“方程式” 不是。-“他们让您想到集合论的形式主义,”-完成任务!-“与人类思想不符的……” –是吗?在实践中,谈论is-a-关系正是您使用类型理论所做的事情。OoΘ
— 左右约

13

正式地说,O(f(n))被一组函数g使得g(n)≤kf(n)对于某一常数k和所有足够大 n。因此,写入它的最准确迂腐方法是T(n)∈O(f(n))。然而,使用=代替 ∈是完全标准,和T(n)=O(f(n))只是意味着T(n)∈O(f(n))。从本质上讲,这永远不会模棱两可,因为我们几乎永远不会操纵集合O(f(n))。

在某种意义上,使用相等使得O(f(n))平均“的一些功能g使得g(n)≤fg(n)表示所有足够大的 n “,这意味着您可以编写f(n)=3n+O(log⁡n)。请注意,这比f(n)=Θ(n)更精确 Θ (n )或f(n)=O(n+log⁡n)。


你也可以写。尽管我承认用f (n )= … = 3 n + O (log n )结束多步计算可能很方便。f(n)−3n∈O(log⁡n)f(n)=…=3n+O(log⁡n)
— 左右约

重新排列仅适用于独立语句。在计算中间,这种事情不起作用,并且多个函数被一起吸收到Landau表示法中,这种情况在计算中间更为常见。(像)。f(x)=e−x(e2x+O(x))=ex+o(1)
— David Richerby

4
我发现这样的计算令人震惊。这些等号不再是双向的。我不知道还有更多写一个问题。我认为那也是滥用符号。基本上,您正在重载=运算符,而我更喜欢提升+和⋅对集合进行运算。f(x)∈ex(e2x+O(x))⊂ex+o(1)=+⋅
— 左右约

一种可能性是使用稍微不同的符号为一组的渐近函数,,以及用于该集合中的未确定的元件,说∈ Ô (ħ )。所以,如果˚F - 克∈ Ö (ħ ),可以写出˚F = 克+ ∈ Ö (ħ )代替暧昧的˚F = 克+ Ö (ħ )。然后,你可以写没有问题∈ Ø (^ h )O(h)∈O(h)f−g∈O(h)f=g+∈O(h)f=g+O(h)。对于未指定的元素其他可能的符号 Ø (^ h )可能是 ˙ Ø(^ h ), Ô(^ h ) ...∈O(h)=f−gO(h)O˙(h)O^(h)
— 米歇尔FIOC

11

序言:大O表示法是一些表示法的强大和含糊不清的经典示例,它是人类心灵喜爱的语言的一部分。不管它造成了多少混乱,仍然要通过符号来传达我们可以轻松识别并有效同意的想法。

我完全理解大O符号的含义。我的问题是,当我们说T(n)=O(f(n)),其中T(n)是大小为n输入上算法的运行时间。

抱歉,如果您理解大O表示法的含义,就不会有问题。

我了解它的语义。但是T(n)和O(f(n))是两回事。T(n)是一个精确的数字,但是O(f(n))不是一个产生数字的函数,因此从技术上讲我们不能说T(n) 等于 O(f(n))。你有什么价值的O(f(n)),您的答案是什么?没有答案。

重要的是语义。重要的是,人们如何能够(容易)就其精确的解释(其中之一)描述我们感兴趣的渐近行为或时间或空间复杂性。默认的精确解释/定义T(n)=O(f(n))是Wikipedia的翻译,

T是实数值或复数值函数,f是实数值函数,都定义在实正数的一些无穷子集上,因此对于所有足够大的 n值,f(n)都是正n。对于所有足够大的n值,T(n)的绝对值最多为f(n)的正常数倍。也就是说,存在一个正实数M和一个实数n0使得

 for all n≥n0,|T(n)|≤Mf(n) for all n≥n0.

请注意,此解释被认为是定义。所有其他的解释和理解(可能会以各种方式极大地帮助您)是次要的和必然的。每个人(嗯,至少这里的每个回答者)都同意这种解释/定义/语义。只要您能运用这种解释,您大多数时候就可能很不错。放松并保持舒适。您不想考虑太多,就像您不想考虑英语,法语或大多数自然语言的某些不规则性一样。只需使用该定义的符号即可。

T(n)是一个精确的数字,但是O(f(n))不是一个产生数字的函数,因此从技术上讲我们不能说T(n) 等于 O(f(n))。您 O (f (n ()))的值是多少,答案是什么?没有答案。O(f(n))

的确,因为这个问题是不恰当的,所以没有答案。T(n)并不代表确切数字。其目的是代表他的名字是一个函数T,其形式参数为n(这是有点界,n在f(n))。如果我们写T=O(f)这同样正确,甚至更正确。如果T是将n映射到n2的函数,而f是将n映射到n 3的函数 n3,通常写f(n)=O(n3)或n2=O(n3)。另请注意,定义并未说明O是否为函数。但这并不是说左手边应该等于右手边!您有理由怀疑等号并不意味着一般意义上的平等,您可以在其中切换等式的两面,并且应该以等价关系作为后盾。(另一个更著名的滥用等号的例子是在大多数编程语言中使用等号来表示赋值,而不是:=像某些语言那样麻烦)。

如果我们仅关注一个平等(我也开始滥用语言。这不是平等;但是,这是平等,因为符号中包含等号或可以将其解释为某种平等),T(n)=O(f(n)),这个答案就完成了。

但是,这个问题实际上还在继续。例如,f(n)=3n+O(log⁡n)什么意思?上面的定义未涵盖这种平等。我们要介绍另一个约定,即占位符约定。这是Wikipedia中所述的占位符约定的完整说明。

在更复杂的用法中,O(⋯)可以出现在方程式的不同位置,甚至在每一侧都出现几次。例如,对于n→∞,以下条件成立。

(n+1)2=n2+O(n)
(n+O(n1/2))(n+O(log⁡n))2=n3+O(n5/2)
nO(1)=O(en)

这些语句的含义如下:对于左侧满足每个O(⋯)任何函数,右侧都有一些满足每个O(⋯)的函数,这样将所有这些函数代入方程式就可以双方平等。例如,上面的第三个方程表示:“对于任何函数f(n)=O(1),都有一些函数g(n)=O(en)使得nf(n)=g(n)。”

您可能需要在此处查看实际使用的占位符约定的另一个示例。

您现在可能已经注意到,我还没有使用大O表示法的集合理论解释。我所做的只是为了显示,即使没有诸如“ O(f(n))是一组函数”之类的集合论解释,我们仍然可以完全而完美地理解大的O表示法。如果您发现以集合论为基础的解释很有用,请继续进行。

您可以检查CLRS的“渐近符号”部分中有关渐进行为符号系列的更详细的分析和使用模式,例如大Θ,Ω,小o,小ω,多变量用法等。在维基百科条目也是一个不错的参考。

最后,存在一些固有的含糊不清/争议,其中O表示法带有多个变量1和2。使用它们时,您可能需要三思。


10

在算法设计手册 [1]中,您可以找到有关此问题的段落:

比较函数时,Big Oh表示法(包括O,Ω和Θ)提供了一个大致的相等概念。看到类似n2=O(n3)的表达式有些令人不快,但始终可以通过按上下限返回定义来解决其含义。将“ =”读为“ 其中一个功能 ”可能是最有启发性的。显然,n2是O(n3)的函数之一。

严格来说(如David Richerby的评论所述),Θ为您提供了一个大致的相等概念,为O了一个小于或等于的粗略概念,以及一个Ω和大于或等于的粗略概念。 。

但是,我同意Vincenzo的回答:您可以简单地将O(f(n))为一组函数,将=符号解释为一组隶属度符号∈。


[1] Skiena,SS《算法设计手册》(第二版)。施普林格(2008)


7

f=O(g)
there exists h∈O(g) such that f=h.

f(n)=n3+O(n2)g(n)∈O(n2)f(n)=n2+g(n)

我发现这种存在量词的解释非常有用,以至于我很想写类似

f(n)≤O(n3)

Cf(n)≤Cn3


≤

2

n2=O(n3)n2nO(n3)nn2O(n3)

O==O>=

O(mn)O(nc)cO(n)nO(2b)

所有这一切都意味着Big-O是一种非正式的表示法,被不精确的事物所束缚,并且您经常必须使用其他上下文来理解作者的言论。

=O∈O


n2=O(n3)nnnn

2

为了强调已经提出过多次的观点,请允许我引用NG de Bruijn的《渐近分析法》:

O0<x<∞O(1)+O(x2)f(x)+g(x)f(x)=O(1)(0<x<∞)g(x)=O(x2)(0<x<∞)x−1O(1)=O(1)+O(x−2)x−1O(1)O(1)+O(x−2)。有时,关系的左侧不是类,而是单个函数。然后,该关系意味着左侧的函数是右侧的类的成员。

=O(x)=O(x2)(x→∞)O(x2)=O(x)(x→∞)=

=

话虽如此,Bender和Orszag的表示法(来自科学家和工程师的高级数学方法)却不那么混乱,值得考虑。关于某些限制,我们说:

f(x)∼g(x)(x→x0)

fg

limx→x0f(x)g(x)=1

和:

f(x)≪g(x)(x→x0)

fg

limx→x0f(x)g(x)=0

但是我认为big-oh表示法的好处是常数因子是任意的。(对于小哦符号,常数就是您所要的。)


0

我在stackoverflow上进行了研究;尽管上面已经说明了对OP的最正确答案(等价类,在下面重述为#1),但这是一个完整的答案:

  1. f=O(⋅)f∈O(⋅){12x2,(5x2−x+5),2.5x,...}x2O(x2)<O(x3)=O(x3+x) (某些集合可能无法比拟; DAG;有关有趣的示例,请参见多项式层次结构)。

    f=Θ(⋅)f∈Θ(⋅)f X gf∈O(g)f∈O(g)g∈f(g)O(g)Θ

  2. f∈Θ(g)x0x>x0gfLOW∗g(x)≤f(x)≤HIGH∗g(x)O(g)k1g(x)+err(x)0≤err(x)≤k2g(x)x>x0x≤x0f=2Θ(x2)f(x)=2k1x2+err(x)0≤err(x)≤k2x2。不过,我们永远都不会写下来……因为这有点愚蠢。但是我认为,以这种方式考虑可能是合理的,并且将保留平等的概念。(在这里我要对负号进行适当的处​​理,这可能很重要。)

    OΘ


x2k1x3+errerrx2=2x+err2x−x2x2
— David Richerby

0

一个更准确的答案是,当我们说一个函数f是“函数g的大O”时。(即x ^ 2 + x是O(x ^ 2))我们说f(x)<C * g(x)对于某些值C和k,其中x> k。这意味着g是f的行为的上限。

例

x ^ 2 + 10x 4是O(x ^ 2 + x)本身就是O(x ^ 2)

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.