ChatGPT解决这个技术问题 Extra ChatGPT

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

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

我很清楚,给定 n2 + n + 1 的形式,最后两项是微不足道的。

具体来说,给定两个分类,2n 和 n*(2n),第二个与第一个的顺序是否相同?那里的额外 n 乘法重要吗?通常资源只是说 xn 呈指数增长并且增长得更快......然后继续前进。

我可以理解为什么它不会因为 2n 会大大超过 n,但是因为它们没有被加在一起,所以在比较两个方程时会非常重要,事实上它们之间的差异总是 n 的一个因子,这至少可以说似乎很重要。

在我看来,鉴于 NLogN 被认为严格比 N 慢,但大多数人并不真正关心多少,可以肯定地说 N2^N 比 2^N 慢,但对人们来说还不够“慢”关心..
@tobias_k,我理解这一点,但考虑 O(n!) 的例子。额外的 n 项真的会有所不同吗? O(n!) 到 O(n*n!) 就像 O(n!) 到 O((n+1)!) 也就是同一个图简单地移动了。但是增长是一样的……在这种情况下,即使一个严格来说很大,增长是不同的吗?这不是时间复杂度所关心的吗?
@JackWu,但大多数人并不真正关心多少,直到您必须使用 nlogn 而不是 n 对数亿条记录进行排序:)
事实上,n! = o((n+1)!),即它严格渐近地增长缓慢。
请注意,这与复杂性理论无关,它“只是”关于渐近线。此外,这类问题在 Computer Science 上可能会更好。

e
emlai

为了回答这个问题,您必须查看大 O (O) 的正式定义。

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

对于您的问题,让 f(n) = n ⋅ 2n 并让 g(n) = 2n。那么 f(n)/g(n)n 仍然会无限增长。因此 f(n) 不属于 O(g(n))


有关更易于阅读的定义,请参阅 here
形式上来说,不能取 O(f(x)/g(x)) 的限制; big-O 通知是一组函数的简写,而不是您可以限制其值的单个函数。但是,我认为如果存在 lim(x->infinity) f(x)/g(x),您确实可以证明 f(x) = O(g(x))
限制不一定存在;对于足够大的 x,该比率只需要以常数为界。例如,2+sin(x) 在 O(1) 中,但 (2+sin(x))/1 没有接近极限,因为 x->infinity。
如果使用 lim sup 而不是 lim,定义将是正确的。
@IvayloStrandjev 请注意,您的简短描述不正确。这对于足够大的 x 必须是正确的,而不是对于 x 的所有值。
c
chepner

快速查看 n⋅2ⁿ 更大的方法是更改变量。让m = 2ⁿ。然后是 n⋅2ⁿ = ( log₂m )⋅m(在 m = 2ⁿ 两边取以 2 为底的对数得到 n = log₂m),您可以很容易地证明 m log₂mm 增长得更快。


谢谢!这是我认为最好的答案。基于正式定义的证明是正确的,但如果你有某种绊脚石需要克服,那么一个非常舒适和熟悉的类比会做得最好、最快。
愚蠢的问题,什么是lg?以 2 为底的对数?
这是一个懒惰的缩写。在计算机科学中,它往往意味着以 2 为底,因为它主要来自分而治之的策略。在大 O 表示法中,它可以表示任何东西,因为一个数字的以 x 为底的对数与其以 y 为底的对数仅相差一个常数因子,而与 x 和 y 无关。
回想起来,我应该注意到 lg 是 ISO 表示以 10 为底的对数,而不是在讨论渐近运行时间时最常用的与基数无关的用法。请参阅en.wikipedia.org/wiki/Logarithm#Particular_bases
好吧,当然,但我不明白为什么 m log m 比 m 增长得更快,而不是 n 2^n 比 2^n 增长得更快。
A
AbcAeffchen

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

根据 Big-O 的正式定义:如果存在常量 c > 0n₀ ≥ 0,则 f(n)O(g(n)) 中,这样对于所有 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
A
AbcAeffchen

我不反对其他说 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)ⁿ,并且对于任何 n,它都小于 1

所以 2ⁿn⋅2ⁿ 增长得慢,最后一个又比 2.000001ⁿ 增长得慢。但他们三个都呈指数级增长。


在最后一个示例中,n*2^n 大于 2.000001^n,直到 n = 34,726,000。那时 2^n 是一个超过 1000 万位的数字,所以这并不重要......
gnasher729 这只是一个常数,我们可以省略它,因为 f(n) 和 c*f(n) 在 big-O 方面具有相同的复杂性。例如 40'000'000*2.000001^n 立即大于 n*2^n。但你是对的,这并不重要,我想说一旦我们达到指数增长(除非我们只得到 n 的小值),这并不重要。
g
gnasher729

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

n 2^n 渐近增长比 2^n 快。这就是那个问题的答案。

但是你可能会问“如果算法 A 需要 2^n 纳秒,而算法 B 需要 n 2^n 纳秒,那么我可以在一秒/分钟/小时/天/月/年找到解决方案的最大 n 是多少?答案是 n = 29/35/41/46/51/54 vs. 25/30/36/40/45/49。在实践中差别不大。

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


佚名

非常简单的答案是“不”

请参阅 2^nn.2^n

如任何 n>0 所见的 n.2^n > 2^n

或者你甚至可以通过在两边应用日志来做到这一点然后你得到

 n.log(2)    <    n.log(2) + log(n) 

因此通过两种类型的分析,即

使用 log 替换数字

我们看到 n.2^n 大于 2^n 可见

所以如果你得到一个等式

O ( 2^n + n.2^n ) 可以替换为 O ( n.2^n)