Performance Eratosthenes的筛选与试验分割时间复杂性

Performance Eratosthenes的筛选与试验分割时间复杂性,performance,algorithm,big-o,primes,sieve-of-eratosthenes,Performance,Algorithm,Big O,Primes,Sieve Of Eratosthenes,根据这个链接 用试除法寻找素数列表的时间复杂度为 n*sqrt(n)/ln(n)^2 用埃拉托斯烯筛寻找素数的时间复杂度为 n*ln(ln(x)) 本文认为,筛分法比试分法具有更好的时间复杂度。但是,如果我绘制这些函数,则筛子显然更差: 此图像是使用查询在上创建的 PLOT ( n*sqrt(n)/ln(n)^2 / (n*ln(ln(n)) )) from 1 to 100 因此,仅基于大O符号,我会得出结论,对于任意大的n,审判分庭应该更好。 这个结论正确吗 但是如果我改变常数,结果就

根据这个链接

用试除法寻找素数列表的时间复杂度为

n*sqrt(n)/ln(n)^2
用埃拉托斯烯筛寻找素数的时间复杂度为

n*ln(ln(x))
本文认为,筛分法比试分法具有更好的时间复杂度。但是,如果我绘制这些函数,则筛子显然更差:

此图像是使用查询在上创建的

PLOT ( n*sqrt(n)/ln(n)^2 / (n*ln(ln(n)) )) from 1 to 100
因此,仅基于大O符号,我会得出结论,对于任意大的n,审判分庭应该更好。 这个结论正确吗

但是如果我改变常数,结果就会改变。似乎不存在独立于常数的渐近散度。根据大O表示法的时间复杂度,得出哪个算法更适合任意大n的结论似乎是毫无用处的。知道哪一个更好的唯一方法是比较实现。我是否得出了错误的结论

论文声称,筛子比试验具有更好的时间复杂度 分开然而,如果我画出这些函数,筛子是清晰的 更糟的因此,仅基于大O符号,我可以得出以下结论: 对于任意大的n,审判庭应该更好。这是吗 结论正确吗

不,结论是错误的,绘图没有显示整个图片,因为您需要考虑常数和更大n值的函数行为

要检查函数fn是否“渐近优于”函数gn,需要检查无穷远处发生的情况。这可以通过以下方式实现:

lim_{n->infinity} f(n)/g(n)
现在,您有3种可能性:

极限为无穷大->fn优于gn 极限是一个常数>0->函数的行为渐近相似,事实上fn在θgn,反之亦然。 极限为0-gn优于fn。 ,我们可以得出结论,第一个-n*sqrtn/lnn^2在使用大O表示法时“较慢”

对于n的“小”值-所有下注都是关闭的,并且大O表示法对于这些情况没有信息。为了对这些情况做出信息性的决定,您需要考虑常数和其他一些依赖于机器的因素。对此的可靠答案不是理论上的,应该通过实证实验和实验来实现

论文声称,筛子比试验具有更好的时间复杂度 分开然而,如果我画出这些函数,筛子是清晰的 更糟的因此,仅基于大O符号,我可以得出以下结论: 对于任意大的n,审判庭应该更好。这是吗 结论正确吗

不,结论是错误的,绘图没有显示整个图片,因为您需要考虑常数和更大n值的函数行为

要检查函数fn是否“渐近优于”函数gn,需要检查无穷远处发生的情况。这可以通过以下方式实现:

lim_{n->infinity} f(n)/g(n)
现在,您有3种可能性:

极限为无穷大->fn优于gn 极限是一个常数>0->函数的行为渐近相似,事实上fn在θgn,反之亦然。 极限为0-gn优于fn。 ,我们可以得出结论,第一个-n*sqrtn/lnn^2在使用大O表示法时“较慢”

对于n的“小”值-所有下注都是关闭的,并且大O表示法对于这些情况没有信息。为了对这些情况做出信息性的决定,您需要考虑常数和其他一些依赖于机器的因素。对此的可靠答案不是理论上的,应该通过实证实验和实验来实现

请注意,与加法或乘法相比,试除法在每一步都使用除法,这在现代处理器上是一种缓慢的操作,而埃拉托什尼筛则不然。因此,试算法可能会有一个更大的常数。另一个因素是筛子所需的空间,但这通常会更便宜

当数字达到100个数量级时,审判庭的效率可能确实相当。但从更大的角度来看:。筛子的真正用途是检查数百万个连续数字的素性

请注意,与加法或乘法相比,试除法在每一步都使用除法,这在现代处理器上是一种缓慢的操作,而埃拉托什尼筛则不然。因此,试算法可能会有一个更大的常数。另一个因素是筛子所需的空间,但这通常会更便宜

当数字达到100个数量级时,审判庭的效率可能确实相当。但从更大的角度来看:。筛子的真正用途是检查数百万个连续数字的素性


您使用的数字不够大。然后画面发生变化:

真正的答案是。在每个特定的n范围内,我们可以用n^a和一些a来近似生长函数。试用版大约为n^1.4和 Eratosthenes的筛分约为n^1.05。现在没有任何混乱:

td n=n**1.5/对数n**2 se n=n*log n _a f n=log f n*1.1/f n/log 1.1 -10K 100K 1M 5M 10M 100M Haskell>map_a td.*1000[1010010005000100001000000]::[Float] [1.2839688, 1.3269958, 1.3557304, 1.3707384, 1.3762819, 1.3917062] Haskell>地图_ase.*1000[1010010005000100001000000]::[Float] [1.0485349, 1.0353413, 1.0274352, 1.0235956, 1.0222284, 1.0185674] 无论常数因子是多少,n^1.4过程都无法长时间击败n^1.05过程


最终,正如您所说,您确实需要比较实现。但是,您可以通过比较它们的经验(即实际测量的运行时间)进行比较,即在给定的n范围内,这是您感兴趣的,上面使用渐近函数模拟的增长顺序。不是函数的绝对值,特别是对于未知的常数因子。

您使用的数字不够大。然后画面发生变化:

真正的答案是。在每个特定的n范围内,我们可以用n^a和一些a来近似生长函数。试验划分约为n^1.4,埃拉托什烯的筛分约为n^1.05。现在没有任何混乱:

td n=n**1.5/对数n**2 se n=n*log n _a f n=log f n*1.1/f n/log 1.1 -10K 100K 1M 5M 10M 100M Haskell>map_a td.*1000[1010010005000100001000000]::[Float] [1.2839688, 1.3269958, 1.3557304, 1.3707384, 1.3762819, 1.3917062] Haskell>地图_ase.*1000[1010010005000100001000000]::[Float] [1.0485349, 1.0353413, 1.0274352, 1.0235956, 1.0222284, 1.0185674] 无论常数因子是多少,n^1.4过程都无法长时间击败n^1.05过程



最终,正如您所说,您确实需要比较实现。但是,您可以通过比较它们的经验(即实际测量的运行时间)进行比较,即在给定的n范围内,这是您感兴趣的,上面使用渐近函数模拟的增长顺序。不是函数的绝对值,尤其是未知常数因子。

以确保。从lim{n->inf}n*sqrtn/lnn^2/n*lnn=infinity,我们可以得出结论,第一个比第二个渐近慢。哇,这是一个快速的解决方案!我最初使用wolfram,但只是为了看情节。似乎很难从图中得出正确的结论。@amit,如果你想写一个答案,我会接受的。如果你在小范围内寻找,你需要考虑常数和其他因素。对此的可靠答案不是理论上的,应该通过实证实验和实验来实现。确保。从lim{n->inf}n*sqrtn/lnn^2/n*lnn=infinity,我们可以得出结论,第一个比第二个渐近慢。哇,这是一个快速的解决方案!我最初使用wolfram,但只是为了看情节。似乎很难从图中得出正确的结论。@amit,如果你想写一个答案,我会接受的。如果你在小范围内寻找,你需要考虑常数和其他因素。对于这一点,可靠的答案不是理论上的,应该通过实证和实验来实现。我将对你的结论做一个更正。对于某些范围的n,可能是试验分割比筛子快。可以得出的结论是,在n0的某个值上,对于n的所有大值,尝试除法都比n0慢。@Zboson您刚才说的是渐近和大O表示法,对于n的“小”值,当涉及到大O表示法时,所有赌注都是无效的,你们应该根据实验得出结论。我想这取决于小到什么程度。对于矩阵乘法,最快的算法具有如此大的常数项,以至于对于所有实际值n,朴素算法都更快。还有一种可能性4:极限不存在。通常,当函数的可能输入子集与其他输入相比特别困难或容易时,就会发生这种情况。我们不太担心这个案子。我想对你的结论做一个更正。对于某些范围的n,可能是试验分割比筛子快。可以得出的结论是,在n0的某个值上,对于n的所有大值,尝试除法都比n0慢。@Zboson您刚才说的是渐近和大O表示法,对于n的“小”值,当涉及到大O表示法时,所有赌注都是无效的,你们应该根据实验得出结论。我想这取决于小到什么程度。对于矩阵乘法,最快的算法具有如此大的常数项,以至于对于所有实际值n,朴素算法都更快。还有一种可能性4:极限不存在。通常,当函数的可能输入子集与其他输入相比特别困难或容易时,就会发生这种情况。我们不太担心这个案子。好的一点是,对于某些范围的n审判分庭原则上可以更快
特别是如果除法不是很慢,但在某一点上它总是比筛子慢。好的一点是,对于n的某些范围,试验除法原则上可以更快,特别是如果除法不是很慢,但在某一点上它总是比筛子慢。关于alogithms分析的wiki链接非常有趣。我需要把它读几遍。关于经验增长顺序的部分是我一直在尝试的。这件事并没有广为人知,这总是让我感到惊讶。这就是为什么我一有机会就鼓吹它的原因我之所以想到TD,是因为我找到了一种减小常数的方法。我不做除法num/den,而是做fact*den>>n其中fact被称为一个幻数,每次我找到一个素数时,我都存储它。这比除法要快得多,因为素数并不频繁,所以我不需要经常确定这些数字。此外,我使用SIMD,并使用AVX2的SSE 8同时测试4个数字。事实上,我有SIMD部分工作,但没有魔术数字部分。但这可能是一个失败的原因,因为SE最终还是赢了。如果TD更快,它可能在短距离内。是的,SE也可以进行大量优化。在2-3-5-7个控制盘上工作,通过适合缓存的段等。控制盘和测试平方根是两种常见的算法。SE不能有效地使用SIMD,至少我想不出怎么做。这是TD为数不多的优势之一,但它最多只能将常数减少4或8倍。关于alogithms分析的wiki链接非常有趣。我需要把它读几遍。关于经验增长顺序的部分是我一直在尝试的。这件事并没有广为人知,这总是让我感到惊讶。这就是为什么我一有机会就鼓吹它的原因我之所以想到TD,是因为我找到了一种减小常数的方法。我不做除法num/den,而是做fact*den>>n其中fact被称为一个幻数,每次我找到一个素数时,我都存储它。这比除法要快得多,因为素数并不频繁,所以我不需要经常确定这些数字。此外,我使用SIMD,并使用AVX2的SSE 8同时测试4个数字。事实上,我有SIMD部分工作,但没有魔术数字部分。但这可能是一个失败的原因,因为SE最终还是赢了。如果TD更快,它可能在短距离内。是的,SE也可以进行大量优化。在2-3-5-7个控制盘上工作,通过适合缓存的段等。控制盘和测试平方根是两种常见的算法。SE不能有效地使用SIMD,至少我想不出怎么做。这是TD为数不多的优点之一,但它最多只能将常数减少4或8倍。