2 ^ n和n * 2 ^ n是否具有相同的时间复杂度?


178

我发现的有关时间复杂度的资源尚不清楚何时可以忽略时间复杂度方程式中的术语,尤其是对于非多项式示例。

对我来说很明显,给定形式为n 2 + n + 1的东西,后两项是无关紧要的。

具体来说,给定两个分类2 n和n *(2 n),第二个的顺序与第一个相同吗?那里的附加n乘数有关系吗?通常,资源只是说x n呈指数形式并且增长得更快...然后继续前进。

我能理解为什么2 n不会超过n,但是为什么不将它们加在一起,所以在比较这两个方程时就显得尤为重要,事实上,它们之间的差总是n的因数,至少可以说这很重要。


8
我认为,鉴于NLogN严格比N慢,但大多数人并不在乎多少,可以肯定地说N2 ^ N比2 ^ N慢,但对人们来说“不够慢”要照顾..
杰克

@tobias_k,我理解这一点,但考虑O(n!)的示例。额外的n项真的会有所不同吗?O(n!)等于O(n * n!),就像O(n!)等于O((n + 1)!)一样,就是简单地移动了同一图。增长是一样的……在这种情况下,即使严格来说是一个大数字,增长也不同吗?这不是复杂性关心的时间吗?
matty-d

3
@JackWu,但是大多数人并不关心多少,除非您必须用nlogn而不是n来排序亿万条记录:)
CB

4
实际上,n! = o((n+1)!)也就是说,它的渐近严格增长得慢。
chepner 2014年

16
请注意,这与复杂性理论无关,它只是关于渐进性。同样,在计算机科学领域,这类问题可能更好。
拉斐尔2014年

Answers:


231

O为了回答这个问题,您将必须使用大O()的形式定义。

定义是当且仅当限制存在(即不是无限)时才f(x)属于。简而言之,这意味着存在一个常数,使得的值永远不会大于。O(g(x))limsupx → ∞ (f(x)/g(x))Mf(x)/g(x)M

在您的问题的情况下,让。然后是这将仍增长无限。因此不属于。f(n) = n ⋅ 2ng(n) = 2nf(n)/g(n)nf(n)O(g(n))


5
有关更易于阅读的定义,请参见此处
Alden 2014年

3
正式地说,您不能限制O(f(x)/g(x)); big-O通知是一组函数的简写,而不是可以限制其值的单个函数。但是,我认为这是真的,你也可以说f(x) = O(g(x)),如果lim(x->infinity) f(x)/g(x)存在。
chepner 2014年

44
该限制不必存在;对于足够大的x,该比率仅需在上面以常数为界。例如,2 + sin(x)在O(1)中,但是(2 + sin(x))/ 1不会接近极限,因为x-> infinity。
user2357112支持Monica 2014年

2
使用lim sup代替的定义将是正确的lim
David Eisenstat 2014年

11
@IvayloStrandjev请注意,您的简短描述不正确。对于足够大的x值,而不是对于的所有值,都必须为真x
K.Steff

85

快速查看n⋅2ⁿ更大的方法是更改​​变量。让m = 2ⁿ。然后n⋅2ⁿ = ( log₂m )⋅m(取m = 2ⁿ给定两边的以2为底的对数n = log₂m),您可以轻松地看出它的m log₂m增长速度比快m


3
谢谢!我认为这是最好的答案。基于形式定义的证明是正确的,但是如果您有某种绊脚石可以克服,那么非常舒适和熟悉的类比将使工作做到最好和最快。
John P

1
愚蠢的问题是lg什么?以2为底的对数?
皮埃尔·阿洛德

3
这是一个懒惰的缩写。在计算机科学中,它倾向于表示基数2,因为它主要来自分而治之策略。用big-O表示法可以表示任何内容,因为数字的基数x对数与基数y对数仅相差一个常数,而与x和y无关。
chepner

3
回顾一下,我应该注意到,这lg是以10为底的对数的ISO表示法,而不是讨论渐近运行时间时最常用的与基底无关的用法。参见en.wikipedia.org/wiki/Logarithm#Particular_bases
chepner 2014年

好的,当然,但是我不明白为什么m log m比m增长更快,而不是n 2 ^ n比2 ^ n增长更快。
djechlin

10

我同意n⋅2ⁿ不在中O(2ⁿ),但我认为应该更加明确,因为限制高级用法并不总是成立。

根据Big-O的形式定义:f(n)O(g(n))存在常量c > 0n₀ ≥ 0并且对于n ≥ n₀我们所有常量而言f(n) ≤ c⋅g(n)。可以容易地证明,对于不存在这样的常量f(n) = n⋅2ⁿg(n) = 2ⁿ。但是,可以显示g(n)在中O(f(n))

换句话说,n⋅2ⁿ由限制2ⁿ。这很直观。尽管它们都是指数的,因此在大多数实际情况下不太可能使用,但我们不能说它们的阶数相同,因为它们的2ⁿ增长速度必定会比慢n⋅2ⁿ


f(n) = 2*2^n我想你的意思是n*2^n
tobias_k 2014年

4

我没有与其他答案争论,认为答案的n⋅2ⁿ增长快于2ⁿ。但是n⋅2ⁿ增长仍然只是指数。

当谈论算法时,我们经常说时间复杂度的增长是指数级的。所以,我们认为是2ⁿ3ⁿeⁿ2.000001ⁿ,或者我们n⋅2ⁿ是同一个组的复杂性呈指数增长。

为了使它具有一些数学意义,f(x)如果存在这样的常数c > 1,我们认为一个函数以指数增长(不快于)。f(x) = O(cx)

因为n⋅2ⁿ常数c可以是大于的任何数字2,所以我们来3。然后:

n⋅2ⁿ / 3ⁿ = n ⋅ (2/3)ⁿ这比1任何事情都要少n

所以2ⁿ增长慢于n⋅2ⁿ,最后一个增长慢于2.000001ⁿ。但是它们三个都成倍增长。


在最后一个示例中,n * 2 ^ n大于2.000001 ^ n,直到n = 34,726,000。那时2 ^ n是一个超过一千万个数字的数字,所以这并不重要……
gnasher729 2014年

1
@ gnasher729这只是一个常量,我们可以忽略它,因为就大O而言,f(n)和c * f(n)的复杂度相同。例如40'000'000 * 2.000001 ^ n立即大于n * 2 ^ n。但是您是对的,这并不重要,我要说的是,一旦达到指数增长,它就无关紧要(除非只有很小的n值)。
Andrey 2014年

2

您问:“第二个顺序是否与第一个相同?另外的n个乘法是否重要?” 这是两个不同的问题,有两个不同的答案。

n 2 ^ n渐近地增长快于2 ^ n。就是那个问题。

但是您可能会问:“如果算法A花费2 ^ n纳秒,而算法B花费n 2 ^ n纳秒,那么我能以秒/分钟/小时/天/月/年/年找到解决方案的最大n是多少?答案是n = 29/35/41/46/51/54与25/30/36/40/45/49,实际上没有太大区别。

在两种情况下,可以在时间T中解决的最大问题的大小为O(ln T)。

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.