SICP练习1.28:Miller-Rabin测试中的假阴性

时间:2016-11-24 11:25:56

标签: algorithm scheme lisp primes sicp

  

练习1.28。不能被愚弄的Fermat测试的一个变体称为Miller-Rabin测试(Miller 1976; Rabin 1980)。这个   从另一种形式的费马小定理开始,该定理指出   如果n是素数而a是任何小于n的正整数,   然后提升到(n - 1)st幂与1 modulo n一致。至   通过Miller-Rabin测试测试数n的素数,我们选择了一个   随机数a< n并使用a将(n - 1)st次幂提高到n   expmod程序。但是,每当我们执行平方步骤时   在expmod中,我们检查一下我们是否发现了一个非平凡的广场   1模的根,''也就是说,一个不等于1或n - 1的数字   square等于1 modulo n。有可能证明,如果这样的话   存在1的非平凡平方根,则n不是素数。也是   可以证明如果n是非素数的奇数,那么,   对于至少一半的数字a< n,以这种方式计算^(n-1)将   揭示1模数n的非平凡平方根。 (这就是为什么   Miller-Rabin测试不能被愚弄。)将expmod过程修改为   如果它发现一个非平凡的平方根1,则发出信号,并使用它   使用类似于的程序实施Miller-Rabin测试   费马测试。通过测试各种已知质数来检查您的程序   非素数。提示:制作expmod信号的一种便捷方法是   它返回0。

(define (fast-prime? n)
  (define (fast-prime-iter n counter)
    (cond ((= counter 1) #t) ; There is no need to check 1
          ((miller-rabin-test n counter)
           (fast-prime-iter n (- counter 1)))
          (else 
            (newline)
            (display counter)
            #f)))
  (fast-prime-iter n (- n 2)))

(define (miller-rabin-test n a)
  (define (expmod base exp m)
    (cond ((= exp 0) 1)
          ((even? exp)
           (nontrivial-square-root?
             (remainder (square (expmod base (/ exp 2) m))
                        m)))
          (else
            (remainder (* base (expmod base (- exp 1) m))
                       m))))
  (= (expmod a (- n 1) n) 1))

(define (nontrivial-square-root? val)
  (if (= val 1)
    0
    val))

我的想法是过滤掉那些所谓的"非平凡的1个模n"使用nontrivial-square-root?程序。如果0为1,则会返回(remainder (square (expmod base (/ exp 2) m)) m),在这种情况下,(expmod base (/ exp 2) m)的平方必须等于1模n(这是因为m总是等于{{1} }),使它成为一个重要的平方根。

虽然n过滤掉了carmichael数字,例如561,1105,1729,2465,2821和6601,但7和13等素数也被报告为复合数。

造成这些假阴性的原因是什么?

1 个答案:

答案 0 :(得分:3)

引号的重要部分标有粗体文字:

  

但是,每当我们在expmod中执行平方步骤时,我们都会检查是否发现了一个“模数n的非平凡平方根”,即数字不等于1或n - 1 其平方等于1模n

因此,在你平方并取余数之前,你必须检查参数不是1或n - 1.这会发生,例如,如果你打电话给var galleryTop = new Swiper('.gallery-top', { spaceBetween: 15, slidesPerView: 2, centeredSlides: true, loop: true }); var galleryThumbs = new Swiper('.gallery-thumbs', { spaceBetween: 10, centeredSlides: true, slidesPerView: 'auto', touchRatio: 0.2, slideToClickedSlide: true, loop: true }); galleryTop.params.control = galleryThumbs; galleryThumbs.params.control = galleryTop; 。通过递归递归,您会注意到有一个评估为(miller-rabin-test 5 3)的调用(nontrivial-square-root? (remainder (square 4) 5))。但是,5仍然是素数,因为4是5 - 1。

因此,在平方部分,您可以调用以下函数:

(nontrivial-square-root? 1)

其中参数是(define (sqrmod-with-check val n) (let ((sqrmod (remainder (square val) n))) (cond ((or (= val (- n 1)) (= val 1)) sqrmod) ((= sqrmod 1) 0) (else sqrmod)))) 调用和expmod。除了在我们找到1模数n的非平凡平方根的情况下,它为你做正方形和余数,当它返回0时。我把它除了三个条件,而不是两个,只是因为可读性。