gpt4 book ai didi

algorithm - Miller-Rabin Scheme 实现不可预测的输出

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:08:29 26 4
gpt4 key购买 nike

我是 Scheme 新手。我尝试并使用 PLT Scheme 实现了 Rabin-Miller 算法的概率变体。我知道这是概率性的,但大多数时候我都得到了错误的结果。我已经使用 C 实现了同样的事情,并且效果很好(从未尝试失败)。我在调试时得到了预期的输出,但是当我运行时,它几乎总是返回不正确的结果。我使用了 Wikipedia 中的算法.

(define expmod( lambda(b e m)
;(define result 1)
(define r 1)
(let loop()
(if (bitwise-and e 1)
(set! r (remainder (* r b) m)))
(set! e (arithmetic-shift e -1))
(set! b (remainder (* b b) m))
(if (> e 0)
(loop)))r))

(define rab_mil( lambda(n k)
(call/cc (lambda(breakout)
(define s 0)
(define d 0)
(define a 0)
(define n1 (- n 1))
(define x 0)
(let loop((count 0))
(if (=(remainder n1 2) 0)
(begin
(set! count (+ count 1))
(set! s count)
(set! n1 (/ n1 2))
(loop count))
(set! d n1)))
(let loop((count k))
(set! a (random (- n 3)))
(set! a (+ a 2))
(set! x (expmod a d n))
(set! count (- count 1))

(if (or (= x 1) (= x (- n 1)))
(begin
(if (> count 0)(loop count))))
(let innerloop((r 0))
(set! r (+ r 1))
(if (< r (- s 1)) (innerloop r))
(set! x (expmod x 2 n))
(if (= x 1)
(begin
(breakout #f)))
(if (= x (- n 1))
(if (> count 0)(loop count)))
)
(if (= x (- s 1))
(breakout #f))(if (> count 0) (loop count)))#t))))

此外,我在 Scheme 中的编程方式是否正确? (我不确定我使用 call/cc 的循环部分的突破。我在某个站点上找到它并从那以后一直在使用它。)

提前致谢。

最佳答案

一般来说,您正在以一种过于“命令式”的方式进行编程;一个更优雅的 expmod 是

(define (expmod b e m)
(define (emod b e)
(case ((= e 1) (remainder b m))
((= (remainder e 2) 1)
(remainder (* b (emod b (- e 1))) m)
(else (emod (remainder (* b b) m) (/ e 2)))))))
(emod b e))

避免使用 set!并递归地执行规则

b^1 == b (mod m)     
b^k == b b^(k-1) (mod m) [k odd]
b^(2k) == (b^2)^k (mod m)

同样,rab_mil 的编程方式非常非方案。这是另一种实现方式。请注意,循环没有“中断”,也没有调用/抄送;相反,突破是作为尾递归调用实现的,它实际上对应于 Scheme 中的“goto”:

(define (rab_mil n k)
;; calculate the number 2 appears as factor of 'n'
(define (twos-powers n)
(if (= (remainder n 2) 0)
(+ 1 (twos-powers (/ n 2)))
0))
;; factor n to 2^s * d where d is odd:
(let* ((s (twos-powers n 0))
(d (/ n (expt 2 s))))
;; outer loop
(define (loop k)
(define (next) (loop (- k 1)))
(if (= k 0) 'probably-prime
(let* ((a (+ 2 (random (- n 2))))
(x (expmod a d n)))
(if (or (= x 1) (= x (- n 1)))
(next)
(inner x next))))))
;; inner loop
(define (inner x next)
(define (i r x)
(if (= r s) (next)
(let ((x (expmod x 2 n)))
(case ((= x 1) 'composite)
((= x (- n 1)) (next))
(else (i (+ 1 r) x))))
(i 1 x))
;; run the algorithm
(loop k)))

关于algorithm - Miller-Rabin Scheme 实现不可预测的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2236359/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com