【问题标题】:Deterministic Miller-Rabin implementation确定性 Miller-Rabin 实现
【发布时间】:2018-01-13 17:32:53
【问题描述】:

我正在尝试使用确定性 Miller-Rabin 算法实现素数检查功能,但结果并不总是正确:检查前 1,000,000 个数字时,它只找到 78,495 而不是 78,498。

这是使用 [2, 7, 61] 作为基础获得的,根据维基百科,对于不超过 4,759,123,141 的值,它应该始终是正确的。
有趣的是,这 3 个缺失的素数正是构成基数的素数(2、7 和 61)。

为什么会这样?我使用的代码如下:

T modular_power(T base, T exponent, T modulo) {
    base %= modulo;
    T result = 1;

    while (exponent > 0) {
        if (exponent % 2 == 1)
            result = (result * base) % modulo;
        base = (base * base) % modulo;
        exponent /= 2;
    }

    return result;
}

bool miller_rabin(const T& n, const vector<T>& witnesses) {
    unsigned int s = 0;
    T d = n - 1;
    while (d % 2 == 0) {
        s++;
        d /= 2;
    }

    for (const auto& a : witnesses) {
        if (modular_power<T>(a, d, n) == 1)
            continue;

        bool composite = true;
        for (unsigned int r = 0; r < s; r++) {
            if (modular_power<T>(a, (T) pow(2, r) * d, n) == n - 1) {
                composite = false;
                break;
            }
        }

        if (composite)
            return false;
    }

    return true;
}

bool is_prime(const T& n) {
    if (n < 4759123141)
        return miller_rabin(n, {2, 7, 61});
    return false; // will use different base
}

【问题讨论】:

  • 进一步 - M-R 断言:{n in odd | n &gt;= 3}。因此,is_prime 中的一个简单拒绝:if ((n &amp; 0x1) == 0) return (n == 2); ... 将所有偶数作为复合数丢弃,(2) 除外。确定性测试明确通过案例:if ((a %= n) == 0)(因为此测试没有告诉我们任何信息),并进一步确保 (0 &lt; a &lt; n) 从这一点开始。
  • 我的 deterministic test 用于 all 无符号 64 位值。如果您只测试 32 位值,您可能会退回到 uint64_t
  • @BrettHale 我用它来解决Project Euler 问题,它们需要相当大的数字,所以uint64_t 可能还不够。您的提示非常好,我已经实现了偶数检查,并且可能会使用您的更多优化,感谢您的帮助!

标签: c++ algorithm primes


【解决方案1】:

当基数和输入相同时,Miller-Rabin 确实不起作用。在这种情况下发生的情况是 ad mod n 为零(因为 a mod n 为零,所以这实际上是将零提高到某个不相关的幂),并且算法的其余部分无法“ escape" 从零开始,并得出结论,您正在处理复合材料。

作为一种特殊情况,Miller-Rabin 从不使用输入 2,因为没有可供选择的碱基。 2 本身没有用,1 也一样,什么都没有。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 2011-01-15
    • 1970-01-01
    • 2013-06-09
    • 2012-06-29
    • 2019-10-04
    相关资源
    最近更新 更多