要求利用Montecarlo测试来求pi
课本中给出的方式是随机两个数的gcd=1的概率为6/pi^2
习题要求利用给定点和矩形 利用S=pi*r*r来获得pi
我们可以通过计算矩阵内的点(此矩阵应为长宽相等的特殊矩阵)包含在r^2内来获取r=1/2时的S,这样我们在最后结果*4 即可获得pi
我们可以通过对随机数进行对区间长的取模再加上区间下限获得给定区间内的随机数
之后我们就可以利用p=((x-a)^2+ (y-b)^2 <= r^2) 来获取p=pi/4
之后,要求我们能够设计重置随机数生成器,显然,利用dispatch的思想我们可以轻松解决,不再赘述
(define (montecarlo trials experiment)
(define (iter trials-remaining trials-pass)
(cond
((= 0 trials-remaining) (/ trials-pass trials))
((experiment) (iter (- trials-remaining 1) (+ trials-pass 1)))
(else (iter (- trials-remaining 1) trials-pass))))
(iter trials 0))
(define (rand-update x)
(let ((a 101) (b 97) (c 10001))
(reminder (+ (* a x) b) c)))
(define rand
(let ((x 100))
(define (generate) (set! x (rand-update x)) x)
(define (reset new-x) (set! x new-x) x)
(define (dispatch m)
(cond
((eq? 'generate m) generate)
((eq? 'reset m) reset)
(else (error "error operaion" m))))
dispatch))
(define (reminder a b)
(if (< a b) a (reminder (- a b) b)))
(define (gcd x y)
(cond
((> x y)
(if
(= y 0) x
(gcd y (reminder x y))))
(else
(if
(= x 0) y
(gcd x (reminder y x))))))
(define (test)
(= (gcd ((rand 'generate)) ((rand 'generate)) ) 1))
(define (get-pi)
(let ((trials 1000))
(sqrt (/ 6 (montecarlo trials test)))))
(define (test2)
(let ((radius 30))
(let
((dx (reminder ((rand 'generate)) radius))
(dy (reminder ((rand 'generate)) radius)))
(<= (+ (square dx) (square dy)) (square radius)))))
(define (get-pi2)
(let ((trials 10000))
(* 4 (montecarlo trials test2))))