有时我看到Θ(n)带有一个奇怪的Θ符号,中间带有一些符号,有时只是O(n)。仅仅是因为没有人知道如何键入此符号而使输入变得懒惰,还是意味着有所不同?
有时我看到Θ(n)带有一个奇怪的Θ符号,中间带有一些符号,有时只是O(n)。仅仅是因为没有人知道如何键入此符号而使输入变得懒惰,还是意味着有所不同?
Answers:
如果算法为Θ(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等人的《算法简介》。
>= \Omega(...)
意思 我知道我们是否说它是的成员\Omega(...)
,但是否大于它?这有什么意义?
有一种简单的方法(我猜是一种技巧)可以记住哪种表示法意味着什么。
所有的Big-O标记都可以视为带有竖线。
当查看Ω时,条形图在底部,因此它是一个(渐近的)下界。
当查看Θ时,条显然在中间。所以这是一个(渐近的)紧边界。
手写O时,通常在顶部完成,然后绘制花样。因此,O(n)是函数的上限。公平地说,这种字体不适用于大多数字体,但这是名称的原始证明。
一个是大“ O”
一个是大Theta
http://en.wikipedia.org/wiki/Big_O_notation
大O表示您的算法将不超过给定表达式(n ^ 2)的步骤执行
大欧米茄(Omega)意味着您的算法将以比给定表达式(n ^ 2)更少的步骤执行
当两个条件对于同一个表达式都成立时,可以使用大theta表示法...。
我将提供一个简单的示例,而不是提供已经在此处进行了漂亮总结的理论定义:
假设运行时间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);
}
Θ(n)
为n 的代码片段的运行时间将线性增长,例如,运行时间T可表示为T(n)= a * n + b。对于较小的n值(例如n = 1或2),这可能不是描述行为的最佳方法-也许您有一些初始化代码花费的时间比f(i)长得多。
一图可以使以前的答案更容易理解:
用英语,
在左侧,请注意,存在一个上限和下限,它们都具有相同的数量级(即g(n))。忽略常数,并且如果上限和下限具有相同的数量级,则可以有效地说f(n)=Θ(g(n))或f(n)处于g(n)的大theta中。
从右边开始,这是更简单的示例,它说上限g(n)只是数量级,并且忽略了常数c(就像所有大O表示法一样)。
让我们考虑f(n) > 0
与g(n) > 0
所有n
。可以考虑一下,因为最快的实算法至少有一个操作并在启动后完成其执行。这将简化演算,因为我们可以使用值(f(n)
)代替绝对值(|f(n)|
)。
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)) ∞
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
结论:我们将大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,大θ和大Ω从定义上不是同一回事,但在我们的嘴和大脑中它们是同一回事。