根据此链接http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
通过试验分部找到素数列表的时间复杂度
n*sqrt(n)/ln(n)^2
和使用Eratosthenes筛选寻找素数的时间复杂度是
n*ln(ln(x))
该论文声称筛子比试验分割具有更好的时间复杂性。但是,如果我绘制这些函数,筛子显然会更糟糕:
此图片是使用查询
在WolframAlpha上创建的PLOT ( n*sqrt(n)/ln(n)^2 / (n*ln(ln(n)) )) from 1 to 100
因此,仅基于大O符号,我会得出结论,对于任意大的n,试验除法应该更好。 这个结论是否正确?
但如果我更改常量,结果可以切换。似乎没有与常数无关的渐近发散。根据大O符号的时间复杂度,总结出哪种算法对于任意大的n更好,似乎没有用。知道哪一个更好的唯一方法是比较实现。 我做出了错误的结论吗?
答案 0 :(得分:1)
该论文声称筛子比试验具有更好的时间复杂性 师。但是,如果我绘制这些功能,筛子很明显 更差。因此,仅基于大O符号我会得出结论 对于任意大的n,试验师应该更好。这是 结论正确吗?
不,结论是错误的,情节没有显示整个图片,因为你需要考虑常数和函数行为以获得更大的n
值。
要检查函数f(n)
是否“渐近优于”函数g(n)
,您需要查看无限远处发生的情况。这可以这样做:
lim_{n->infinity} f(n)/g(n)
现在,您有三种可能性:
From checking your functions on wolfram alpha,我们可以得出结论,第一个 - n*sqrt(n)/ln(n)^2
是'较慢',当涉及到大O符号时。
对于n
的'小'值 - 所有投注均已关闭,并且大O符号对于这些情况不提供信息。要对这些情况做出信息性的决定,您需要考虑常量和其他事物(有些是机器相关的)。对此的可靠答案不是理论上的,应该使用经验实验和statistic tests来实现。
答案 1 :(得分:1)
请注意,试验部门在每个步骤都使用除法(与加法或乘法相比,现代处理器上的操作速度较慢),而Eratosthenes的筛子则没有。因此,试验分割方法可能会有更大的常数。另一个因素是筛子所需的空间,但通常会更便宜。
当数字为100阶时,试验部门的效率确实可以相提并论。尽管如此:(link)。筛选的真实用例是当你想要检查数百万个连续数字的素数时。
答案 2 :(得分:1)
你没有使用足够多的数字。然后情况改变了:
真正的答案是empirical orders of growth。在n
的每个特定范围内,我们可以通过n^a
与a
近似估算增长函数。审判师约为n^1.4
,而Eratosthenes的筛子约为n^1.05
。现在没有混淆:
td n = n**1.5 / (log n)**2
se n = n * log (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)) [10,100,1000,5000,10000,100000] :: [Float]
[1.2839688, 1.3269958, 1.3557304, 1.3707384, 1.3762819, 1.3917062]
Haskell> map (_a se.(*1000)) [10,100,1000,5000,10000,100000] :: [Float]
[1.0485349, 1.0353413, 1.0274352, 1.0235956, 1.0222284, 1.0185674]
无论常数因素如何, n ^ 1.4 过程都不会超过 n ^ 1.05 过程。
最终,您需要比较实现,正如您所说。但是你可以通过比较它们的经验(即实际测量的运行时间) local (即在n
的给定范围内进行比较,这是您感兴趣的)< em>增长顺序(通过使用渐近函数在上面模拟)。 不函数的绝对值,尤其是未知常数因子。