【问题标题】:Miller-Rabin test (SICP 1.28)Miller-Rabin 测试 (SICP 1.28)
【发布时间】:2019-10-04 08:02:56
【问题描述】:

费马检验的一种变体被称为米勒-拉宾检验(Miller-Rabin 检验)(Miller 1976;Rabin 1980)。这从费马小定理的另一种形式开始,它指出如果 n 是一个素数并且 a 是任何小于 n 的正整数,则 a(n - 1) 次幂等于 1n

为了通过 Miller-Rabin 测试来测试一个数 n 的素数,我们选择一个小于 n 的随机数 a 并提高a(n - 1)st 幂模 n 使用expmod 过程。但是,每当我们在expmod 中执行平方步骤时,我们都会检查是否发现了“1n 的非平凡平方根”,即数不等于 1n - 1,其平方等于 1n

可以证明,如果1的这样一个非平凡平方根存在,那么n不是素数。也可以证明,如果 n 是一个非素数的奇数,那么,对于至少一半的数 a ,计算 an-1 以这种方式将显示 1n 的非平凡平方根。 (这就是为什么 Miller-Rabin 测试不能被愚弄的原因。)

修改expmod 过程以在发现1 的非平凡平方根时发出信号,并使用该过程以类似于fermat-test 的过程实现米勒-拉宾测试。通过测试各种已知的素数和非素数来检查你的程序。提示:制作expmod 信号的一种便捷方法是让它返回 0。

这是我目前所拥有的。

(define (square x) (* x x))
(define (even? n) (= (remainder n 2)))

(define (expmod-signal b n m)
  (define (check a)
    (and (not (= a 1))
         (not (= a (- n 1)))
         (= (square a) (remainder 1 n))))
  (cond ((= n 0) 1)
        ((check b) 0)
        ((even? n) (remainder (square (expmod-signal b (/ n 2) m)) m))
        (else (remainder (* b (expmod-signal b (- n 1) m)) m))))

(define (miller-rabin n)
  (define (fail? n a)
    (or (= n 0) (not (= n a))))
  (define (try a)
    (cond ((= a 1) #t)
          ((fail? (expmod-signal a (- n 1) n) a) #f)
          (else (try (- a 1)))))
  (try (- n 1)))

我认为我正确实现了miller-rabin,但我不明白修改后的expmod 应该如何工作。你检查正方形之前的数字还是正方形之后的数字?我不知道从阅读问题。

【问题讨论】:

    标签: scheme primes sicp modular-arithmetic primality-test


    【解决方案1】:

    我通过在expmod-signal 中使用expmod 的原始定义解决了这个问题。在我的测试中的某个地方,expmod-signal 自然地返回零并弄乱了测试。我误解了检查功能,“其平方等于1模n”的意思是检查a^2 % m = 1。这个检查函数的工作方式是,如果参数是 1 mod n 的非平凡平方根,则返回 0,否则返回参数。如果它返回零,则零会传播到expmod-signal 的其余部分并返回。

    (define (square x) (* x x))
    (define (even? n) (= (remainder n 2)))
    
    (define (expmod base exp m)
      (cond ((= exp 0) 1)
            ((even? exp) (remainder (square (expmod base (/ exp 2) m)) m))
            (else (remainder (* base (expmod base (- exp 1) m)) m))))
    
    (define (expmod-signal b n m)
      (define (check a)
        (if (and (not (= a 1))
                 (not (= a (- n 1)))
                 (= (remainder (square a) n) 1))
            0
            a))
      (cond ((= n 0) 1)
            ((even? n) (remainder (square (check (expmod b (/ n 2) m))) m))
            (else (remainder (* b (expmod b (- n 1) m)) m))))
    
    (define (miller-rabin n)
      (define (fail? a)
        (or (= a 0) (not (= a 1))))
      (define (try a)
        (cond ((= a 1) #t)
              ((fail? (expmod-signal a (- n 1) n)) #f)
              (else (try (- a 1)))))
      (try (- n 1)))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-27
      • 2013-06-09
      • 1970-01-01
      • 2019-09-21
      • 2012-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多