我正在学习试验分组素性测试的基础知识,因此,在代码中实现它。使用许多技巧可以提高算法的性能:
1)运行试验部门只能达到平方根(n)
2)通过创建一个直至平方根(n)的筛子来交易记忆,然后仅在创建筛子的素数上运行试验分区
但是如果n%6
(n mod 6)的值被发现为1 or 5
(使用6k +/- 1规则),我找不到将结果作为复合返回的想法。在我们的素数测定测试中使用此规则是否会改善其性能?如果是的话,为什么没有在任何地方提到它?如果不是,为什么会这样呢?
感谢。
答案 0 :(得分:3)
看起来你属于初学者级别以上的类别(那些永远不会想出这个想法的人)和低于寻求极端性能的人。所以这个想法有点难以向初学者解释,对于非常先进的人来说似乎微不足道。
它可以将运行时间减少三分之一,或者让您在同一时间内测试多50%的数字。你可以通过减少除数不是太大的测试来节省更多:让我们说你测试一个大约十亿的数字。你有一个循环,除数d = 6k-1,你想测试d和d + 2 = 6k + 1。所以你只测试d ^2≤p,你不测试(d + 2)^2≤p。最坏的情况是,你测试一个除数超过你需要的。最好的情况是,你节省了几千次测试(d + 2)^2≤p。
你可以通过观察唯一可能的≥30的素数是30k + 1,7,11,13,17,19,23,29,避免30k + 5和30k + 25来节省更多。
答案 1 :(得分:1)
您对n % 6
进行测试的想法完全等同于测试n % 2
和n % 3
- 因此,如果您将后者作为普通试验部门的一部分,则执行前者是多余的。
付出的一个密切相关的想法是(在考虑2和3之后)仅查看6k+1
,6k-1
形式的试验除数,如@ gnasher729他们的优秀答案解释道。
答案 2 :(得分:1)
这个技巧的工作方式:制作一堆小素数的M的乘积。然后,当测试数字N时,如果(N%M)为0或者具有与M共同的因子,则可以立即说N是复合的。
你使用了6,2和3的乘积。在可能的模数0,1,2,3,4,5中,只有1和5不具有2或3的因子。
然而,对于6来说没有什么特别之处 - 你可以用任何模数做同样的技巧,尽管你想让它成为小素数的乘积,以最大化复合模量的密度。请注意,在进行此检查后(如gnasher所示),您只需要测试没有与M共同的因子的试验除数。
答案 3 :(得分:1)
此处的一般方法称为Wheel Factorization。最简单的轮子是专门处理2,然后测试奇数:2轮。下一个最简单的是2,3轮,你在问题中提到。 @ gnasher729给出了上面2,3,5轮的数字。
您可以通过从5开始交替添加2和4来生成2,3轮的数字。
伪代码:
EmailField
这比Sieve使用更少的内存,但对于非常大的素数来说太慢了。