好的,我有一个项目需要完成,但我不理解它。问题是我有两个算法:O(n^2)和O(n*log2n)。
无论如何,在项目信息中我发现如果n<100,那么O(n^2)更有效率,但如果n>=100,那么O(n*log2n)更有效率。我应该使用数字、文字或绘制图片的方式演示一个例子。但问题是,我不懂这个算法,也不知道如何进行演示。
有人能帮助我理解这是如何工作的吗?
好的,我有一个项目需要完成,但我不理解它。问题是我有两个算法:O(n^2)和O(n*log2n)。
无论如何,在项目信息中我发现如果n<100,那么O(n^2)更有效率,但如果n>=100,那么O(n*log2n)更有效率。我应该使用数字、文字或绘制图片的方式演示一个例子。但问题是,我不懂这个算法,也不知道如何进行演示。
有人能帮助我理解这是如何工作的吗?
好问题。实际上,我总是展示这三张图片:
因此,O(N*log(N))
比O(N^2)
要好得多。它比O(N^2)
更接近于O(N)
。
但是你的O(N^2)
算法在现实生活中对于N < 100
来说更快。这有很多原因,可能是由于更好的内存分配或其他“非算法”效应。也许O(N*log(N))
算法需要一些数据准备阶段或者O(N^2)
迭代时间更短。无论如何,在大到足够的N时,大O符号才是合适的。
如果您想证明为什么某个算法对于小的N更快,您可以测量两种算法的每次迭代的执行时间和固定的开销,然后使用它们来修正理论图:
或者只需测量不同的Ns
上两种算法的执行时间并绘制实验数据图表。
如果你有疑问,只需询问wolframalpha。
在这种情况下,它显示:
n log(n)
lim --------- = 0
n^2
或者你也可以自行计算极限:
n log(n) log(n) (Hôpital) 1/n 1
lim --------- = lim -------- = lim ------- = lim --- = 0
n^2 n 1 n
这意味着n^2
增长得更快,因此当n
足够大时,n log(n)
较小(更好)。
大O符号是渐进复杂度的一种表示方法。这意味着它在N趋于无穷大时计算复杂度。
对于小的N,会有许多其他因素影响。可能一个算法具有O(n^2)的循环迭代,但每次迭代非常短,而另一个算法具有O(n)的迭代,但每次迭代非常长。对于较大的N,线性算法将更快。对于小的N,二次算法将更快。
因此,对于小的N,只需测量两个算法并查看哪个更快即可。无需深入了解渐进复杂度。
顺便提一下,不要写对数的底数。大O符号忽略常数 - O(17 * N)与O(N)相同。由于log2N只是ln N / ln 2
,对数的底数只是另一个常数,并被忽略。
让我们比较一下,
一方面,我们有:
n^2 = n * n
另一方面,我们有:
nlogn = n * log(n)
将它们并排放置:
n * n versus n * log(n)
我们将除以一个常见的项n
,得到:
n versus log(n)
让我们比较一下数值:
n = 10 log(n) ~ 2.3
n = 100 log(n) ~ 4.6
n = 1,000 log(n) ~ 6.9
n = 10,000 log(n) ~ 9.21
n = 100,000 log(n) ~ 11.5
n = 1,000,000 log(n) ~ 13.8
所以我们有:
n >> log(n) for n > 1
n^2 >> n log(n) for n > 1
e ~ 2.7
)。如果你在处理二叉树,可以使用基数为2
。如果你选用基数为10
,那么你将得到 10^n
,而 log10
将是最左边的数字后面的位数:1000 = 10^3 = 10*10*10, log10(1000) = log10(10^3) = 3
。 - Khaled.Kbig-O
”表示绘制函数的渐近最小上界之一,而不是指集合 O(f(n))
。O(n log n)
(绿线)增长速度比O(n^2)
(橙线)要慢。这就是为什么(对于最坏情况)O(n log n)
比O(n^2)
更理想的原因,因为你可以增加输入大小,而前者的增长速度比后者慢。我们有两种比较两个算法的方法 -> 第一种方法非常简单,只需进行比较并应用限制条件
T1(n)-Algo1
T2(n)=Alog2
lim (n->infinite) T1(n)/T2(n)=m
(i)如果m=0,Algo1比Algo2更快。
(ii)m=k 两者相同
(iii)m=无穷大,Algo2更快。
*第二种方法与第一种方法相比较简单,只需对两者取对数,但不要忽略多个常数。
Algo 1=log n
Algo 2=sqr(n)
keep log n =x
Any poly>its log
O(sqr(n))>o(logn)
首先,将渐近复杂度与 N 约束混合比较并不完全正确。例如,我可以说:
O(n^2)
比 O(n * log(n))
更慢,因为 大 O 符号 的定义将包括 n 无限增长
。
对于特定的 N
,只需比较 N^2 * ALGORITHM_CONSTANT
和 N * log(N) * ALGORITHM_CONSTANT
即可确定哪个算法更快,其中 ALGORITHM_CONSTANT
取决于算法。例如,如果我们需要遍历数组两次才能完成工作,则渐近复杂度将为 O(N)
,而 ALGORITHM_CONSTANT
将为 2
。
此外,我想提到 O(N * log2N)
(我假设基数为 2
的对数是 log2N)实际上与 O(N * log(N))
相同,因为它们具有相同的对数属性。
我是一名数学家,所以我将尝试解释为什么对于小的n值,n^2比nlogn更快,使用一个简单的极限,当n-->0时:
lim n^2 / nlogn = lim n / logn = 0 / -inf = 0
因此,对于小的n值(在这种情况下,“小值”是存在于[1,99]中的n),nlogn比n^2更快,因为我们看到极限=0。 但为什么n-->0?因为算法中的n可以取“大”值,所以当n<100时,它被认为是非常小的值,因此我们可以取极限n-->0。