使用C++查找质数的最快算法是什么?我已经使用了筛法,但我仍希望它更快!
丹·伯恩斯坦的 primegen 实现了一个非常快速的 Atkin筛法,比 Eratosthenes筛法 更高效。他的网页上提供了一些基准信息。
如果需要非常快的速度,您可以包含一个质数列表:
http://www.bigprimes.net/archive/prime/
如果您只想知道某个数字是否为质数,可以在维基百科上列出各种素性测试。它们可能是确定大数字是否为质数的最快方法,尤其是因为它们可以告诉您一个数字不是质数。
到目前为止,我相信最快的质数测试算法是强似素数(SPRP)算法。我引用了Nvidia CUDA论坛上的话:
数论中更实际的细分问题之一涉及素数的识别。给定N,如何有效地确定它是否为素数?这不仅是一个理论问题,在编码时可能需要真正解决,也许当您需要在某些范围内动态查找素数哈希表大小时。如果N大约为2^30,您真的想做30000个除法测试来搜索任何因子吗?显然不行。更多信息请参见: http://primes.utm.edu/prove/prove2_3.html 和 http://forums.nvidia.com/index.php?showtopic=70483
如果您只需要一种生成非常大的质数的方法,并且不关心生成所有小于整数n的质数,那么可以使用Lucas-Lehmer测试来验证梅森素数。梅森素数是2^p -1的形式。我认为Lucas-Lehmer测试是发现梅森素数最快的算法。
如果您不仅想使用最快的算法,而且还想使用最快的硬件,请尝试使用Nvidia CUDA实现它,编写CUDA内核并在GPU上运行它。
如果您发现足够大的质数,甚至可以赚取一些奖金,EFF提供从50K美元到250K美元的奖励: https://www.eff.org/awards/coop
有一种100%的数学测试可以检查一个数字P
是质数还是合数,它被称为AKS素性测试。
这个概念很简单:给定一个数P
,如果(x-1)^P - (x^P-1)
的所有系数都能被P
整除,则P
是一个质数,否则它是一个合数。
例如,给定P=3
,将得到多项式:
(x-1)^3 - (x^3 - 1)
= x^3 + 3x^2 - 3x - 1 - (x^3 - 1)
= 3x^2 - 3x
系数都可以被3
整除,因此这个数是质数。
当P = 4
时,它不是一个质数的例子如下:
(x-1)^4 - (x^4-1)
= x^4 - 4x^3 + 6x^2 - 4x + 1 - (x^4 - 1)
= -4x^3 + 6x^2 - 4x
在这里,我们可以看到系数6
不是4
的倍数,因此它不是质数。
多项式(x-1)^P
将有P+1
项,并且可以使用组合找到。因此,此测试将在O(n)
运行时间内运行,因此我不知道这会有多大用处,因为您可以简单地迭代i
从0到p
并测试余数。
x
在 (x-1)^P - (x^P-1)
中代表什么?你有这方面的示例代码吗?用 C++ 写一个判断整数是否为质数的程序。 - kiLLuaRabin-Miller 是一种标准的概率素性测试。您运行它 K 次,输入数字要么绝对是合成数,要么是可能是质数,错误概率为 4-K。(进行几百次迭代,它几乎肯定会告诉您真相)
还有一种非概率(确定性)Rabin Miller 的变体。
Great Internet Mersenne Prime Search(GIMPS)已经发现了世界上最大的素数记录(截至2017年6月为274,207,281 - 1),使用几种算法,但这些都是特殊形式的素数。然而,上述GIMPS页面确实包括一些一般的确定性素性测试。它们似乎表明,“最快”的算法取决于要测试的数字的大小。如果您的数字适合64位,则可能不应使用旨在处理数百万位数的质数的方法。
这取决于你的应用程序。有一些考虑因素:
米勒-拉宾和类似的测试仅对大于某个大小的数字(大约在几百万左右)比筛法更快。在此之下,如果你只有几个数字,使用试除法;如果你需要所有的质数,则使用筛法更快。
这是我一直在玩弄的Python Eratosthenes筛法实现。
def eratosthenes(maximum: int) -> list[int | None]:
"""
Find all the prime numbers between 2 and `maximum`.
Args:
maximum: The maximum number to check.
Returns:
A list of primes between 2 and `maximum`.
"""
if maximum < 2:
return []
# Discard even numbers by default.
sequence = dict.fromkeys(range(3, maximum+1, 2), True)
for num, is_prime in sequence.items():
# Already filtered, let's skip it.
if not is_prime:
continue
# Avoid marking the same number twice.
for num2 in range(num ** 2, maximum+1, num):
# Here, `num2` might contain an even number - skip it.
if num2 in sequence:
sequence[num2] = False
# Re-add 2 as prime and filter out the composite numbers.
return [2] + [num for num, is_prime in sequence.items() if is_prime]
这段代码在一部普通的三星Galaxy A40手机上处理10000000个数字大约需要16秒。
欢迎提出建议!
-> list[int]
。一个空的列表(你可能用 None
来引用)仍然是一个 int
的列表。 - matheburgif num2 % 2:
替换if num2 in sequence:
。这样做会显著提高速度(而且我认为更易读)。 - matheburg#include <iostream>
#include <math.h>
using namespace std;
int isPrime(int p)
{
int tc = pow(2, p) - 2;
if (tc % p == 0)
{
cout << p << "is Prime ";
}
else
{
cout << p << "is Not Prime";
}
return 0;
}
int main()
{
int p;
cin >> p;
isPrime(p);
return 0;
}
我最近编写了这段代码,用于计算数字的总和。它可以轻松修改,以查找一个数字是否为质数。基准测试数据在代码顶部。
// built on core-i2 e8400
// Benchmark from PowerShell
// Measure-Command { ExeName.exe }
// Days : 0
// Hours : 0
// Minutes : 0
// Seconds : 23
// Milliseconds : 516
// Ticks : 235162598
// TotalDays : 0.00027217893287037
// TotalHours : 0.00653229438888889
// TotalMinutes : 0.391937663333333
// TotalSeconds : 23.5162598
// TotalMilliseconds : 23516.2598
// built with latest MSVC
// cl /EHsc /std:c++latest main.cpp /O2 /fp:fast /Qpar
#include <cmath>
#include <iostream>
#include <vector>
inline auto prime = [](std::uint64_t I, std::vector<std::uint64_t> &cache) -> std::uint64_t {
std::uint64_t root{static_cast<std::uint64_t>(std::sqrtl(I))};
for (std::size_t i{}; cache[i] <= root; ++i)
if (I % cache[i] == 0)
return 0;
cache.push_back(I);
return I;
};
inline auto prime_sum = [](std::uint64_t S) -> std::uint64_t {
std::uint64_t R{5};
std::vector<std::uint64_t> cache;
cache.reserve(S / 16);
cache.push_back(3);
for (std::uint64_t I{5}; I <= S; I += 8)
{
std::uint64_t U{I % 3};
if (U != 0)
R += prime(I, cache);
if (U != 1)
R += prime(I + 2, cache);
if (U != 2)
R += prime(I + 4, cache);
R += prime(I + 6, cache);
}
return R;
};
int main()
{
std::cout << prime_sum(63210123);
}
int p[] = {2, 3};
是否可以被认为是“最快的质数查找算法”? - user1196549