BigInteger.isProbablePrime 似乎比它说的要确定得多
BigInteger.isProbablePrime seems much more certain than it says it is
我理解 certainty 参数的意思是:
certainty - a measure of the uncertainty that the caller is willing to tolerate: if the call returns true the probability that this BigInteger is prime exceeds (1 - 1/2certainty)
从我的实验来看,它似乎超过了很多!下面的代码找到 2 到 100 万之间的“可能素数”,并检查一组确定的素数以查看它是否是误报。
我使用的确定性参数为 2。因此我预计只有 75% 的“可能素数”将是实际素数。 (1 - 1/22 = 0.75 = 75%.)
实际上,它在 99.9% 的时间里都是正确的。
我对“确定性”的理解正确吗?我怀疑如果我在实验中看到的确定性超出我的预期那么多。
import java.math.BigInteger;
import java.util.BitSet;
import static java.lang.Math.sqrt;
public class PrimesCalculator {
public final int max;
private final BitSet sieve; // Set of all non-primes from 2 to max.
public PrimesCalculator(int max) {
this.max = max;
sieve = new BitSet(max+1);
for (int n = 2, sqrtMax = (int) sqrt(max); n < sqrtMax; n++)
for (int i = n * 2; i < max; i += n)
sieve.set(i);
}
public boolean isPrime(int n) {
return !sieve.get(n);
}
public static void main(String[] args) {
PrimesCalculator calc = new PrimesCalculator(1_000_000);
int numPrimes = 0;
int numProbablePrimes = 0;
for (int i = 2; i < calc.max; i++)
if (BigInteger.valueOf(i).isProbablePrime(2)) {
numProbablePrimes++;
if (calc.isPrime(i))
numPrimes++;
}
System.out.printf("%s/%s (%s%%)%n", numPrimes, numProbablePrimes, numPrimes / (numProbablePrimes / 100.0));
}
}
您引用的文档是正确的。
certainty - a measure of the uncertainty that the caller is willing to tolerate: if the call returns true the probability that this BigInteger is prime exceeds (1 - 1/2certainty)
99.9% 确实超过了 1 - 1/(22) = 3/4,所以你向我们展示的没有任何问题。
该实现不保证 恰好是 的概率,它只是提供了一个实现,其误差是 绝对受限 的。
大多数质量素性测试程序都会对小素数进行大量优化,或者更确切地说,其除数是小合数的数字。这些可能会在算法的随机方面之前启动,从而导致 higher-than-usual 小素数的准确性。
这些陈述经常引起混淆。我会尝试在这里更好地解释它。
Java 的 BigInteger.isProbablePrime()
根本不包含对小整数的优化,除了 0、1 和 2 被视为特殊情况并且除 2 之外的所有偶数整数都立即声明为复合。
使用 Miller-Rabin (MR) 素性测试检查所有其他奇数的素性。此外,如果整数是 100 位或更大,还会使用称为 Lucas-Lehmer 测试的东西对其进行检查。
MR 是一个复杂的素数测试,其解释和分析超出了 SO 答案的范围。关键是,就 MR 而言,并非所有复合材料都生而平等。非常非常小的一部分很难发现它们的复合性。举几个例子:在小奇数组合中,91、703 和 1891 是困难的。 MR 通过尝试多次随机尝试来发现整数的复合性来克服这个问题。 Rabin 的分析表明,对于表现最差的复合材料,单次随机尝试仍有至少 75% (3/4) 的概率揭示其复合材料。
certainty
参数几乎等同于指定 MR 算法需要执行的随机尝试次数。实际上,certainty
参数与随机尝试次数的关系比较复杂,我自己也不是很明白。
作为查看不同复合材料性能的实验,请将您的程序更改为只是反复尝试确认 1891 年的复合材料。您会看到接近 75% 的成功率。
MR-stubborn 个相对较小的复合材料列表是 here。
我理解 certainty 参数的意思是:
certainty - a measure of the uncertainty that the caller is willing to tolerate: if the call returns true the probability that this BigInteger is prime exceeds (1 - 1/2certainty)
从我的实验来看,它似乎超过了很多!下面的代码找到 2 到 100 万之间的“可能素数”,并检查一组确定的素数以查看它是否是误报。
我使用的确定性参数为 2。因此我预计只有 75% 的“可能素数”将是实际素数。 (1 - 1/22 = 0.75 = 75%.)
实际上,它在 99.9% 的时间里都是正确的。
我对“确定性”的理解正确吗?我怀疑如果我在实验中看到的确定性超出我的预期那么多。
import java.math.BigInteger;
import java.util.BitSet;
import static java.lang.Math.sqrt;
public class PrimesCalculator {
public final int max;
private final BitSet sieve; // Set of all non-primes from 2 to max.
public PrimesCalculator(int max) {
this.max = max;
sieve = new BitSet(max+1);
for (int n = 2, sqrtMax = (int) sqrt(max); n < sqrtMax; n++)
for (int i = n * 2; i < max; i += n)
sieve.set(i);
}
public boolean isPrime(int n) {
return !sieve.get(n);
}
public static void main(String[] args) {
PrimesCalculator calc = new PrimesCalculator(1_000_000);
int numPrimes = 0;
int numProbablePrimes = 0;
for (int i = 2; i < calc.max; i++)
if (BigInteger.valueOf(i).isProbablePrime(2)) {
numProbablePrimes++;
if (calc.isPrime(i))
numPrimes++;
}
System.out.printf("%s/%s (%s%%)%n", numPrimes, numProbablePrimes, numPrimes / (numProbablePrimes / 100.0));
}
}
您引用的文档是正确的。
certainty - a measure of the uncertainty that the caller is willing to tolerate: if the call returns true the probability that this BigInteger is prime exceeds (1 - 1/2certainty)
99.9% 确实超过了 1 - 1/(22) = 3/4,所以你向我们展示的没有任何问题。
该实现不保证 恰好是 的概率,它只是提供了一个实现,其误差是 绝对受限 的。
大多数质量素性测试程序都会对小素数进行大量优化,或者更确切地说,其除数是小合数的数字。这些可能会在算法的随机方面之前启动,从而导致 higher-than-usual 小素数的准确性。
这些陈述经常引起混淆。我会尝试在这里更好地解释它。
Java 的 BigInteger.isProbablePrime()
根本不包含对小整数的优化,除了 0、1 和 2 被视为特殊情况并且除 2 之外的所有偶数整数都立即声明为复合。
使用 Miller-Rabin (MR) 素性测试检查所有其他奇数的素性。此外,如果整数是 100 位或更大,还会使用称为 Lucas-Lehmer 测试的东西对其进行检查。
MR 是一个复杂的素数测试,其解释和分析超出了 SO 答案的范围。关键是,就 MR 而言,并非所有复合材料都生而平等。非常非常小的一部分很难发现它们的复合性。举几个例子:在小奇数组合中,91、703 和 1891 是困难的。 MR 通过尝试多次随机尝试来发现整数的复合性来克服这个问题。 Rabin 的分析表明,对于表现最差的复合材料,单次随机尝试仍有至少 75% (3/4) 的概率揭示其复合材料。
certainty
参数几乎等同于指定 MR 算法需要执行的随机尝试次数。实际上,certainty
参数与随机尝试次数的关系比较复杂,我自己也不是很明白。
作为查看不同复合材料性能的实验,请将您的程序更改为只是反复尝试确认 1891 年的复合材料。您会看到接近 75% 的成功率。
MR-stubborn 个相对较小的复合材料列表是 here。