我试图确定落在给定圆(半径1)内的弹珠的数量,因为它们具有随机的x和y坐标。
我的总体目标是通过使用蒙特卡罗采样乘以4(圆圈内的弹珠数)/(弹珠总数)来找到pi的近似值。
我打算让我的功能计算圈内的弹珠数量,但我无法理解为什么它不起作用。任何有关遵循此功能的帮助将不胜感激。
如果上述帮助请求不明确,请发表评论。
(define(monte-carlo-sampling n)
(let ((x (- (* 2 (random)) 1))
(y (- (* 2 (random)) 1)))
(cond((= 0 n)
* 4 (/ monte-carlo-sampling(+ n 1) n)
((> 1 n)
(cond((< 1 (sqrt(+ (square x) (square y))) (+ 1 (monte-carlo-sampling(- n 1)))))
((> 1 (sqrt(+ (square x) (square y))) (monte-carlo-sampling(- n 1))))
)))))
答案 0 :(得分:2)
您的括号全部搞砸了,<
的参数顺序错误。以下是代码修正后的样子:
(define (monte-carlo-sampling n)
(let ((x (- (* 2 (random)) 1))
(y (- (* 2 (random)) 1)))
(cond ((= n 0)
0)
(else
(cond ((< (sqrt (+ (square x) (square y))) 1)
(+ 1 (monte-carlo-sampling (- n 1))))
(else
(monte-carlo-sampling (- n 1))))))))
返回点击次数。您必须使用外部函数将命中数转换为pi估计值,例如:
(define (estimate-pi n)
(* 4 (/ (monte-carlo-sampling n) n)))
如果由我决定的话,这就是我写整篇文章的方式:
(define (estimate-pi n)
(let loop ((i 0)
(hits 0))
(cond ((>= i n)
(* 4 (/ hits n)))
((<= (hypot (sub1 (* 2 (random)))
(sub1 (* 2 (random)))) 1)
(loop (add1 i) (add1 hits)))
(else
(loop (add1 i) hits)))))
(在Racket上测试,使用我在上一个答案中给出的hypot
的定义。如果您不使用Racket,则必须将add1
和sub1
更改为适当的。)
答案 1 :(得分:1)
我在blog写了一个解决这个问题的方法;内部函数被称为sand
,因为我扔的是沙粒而不是大理石:
(define (pi n)
(define (sand?) (< (+ (square (rand)) (square (rand))) 1))
(do ((i 0 (+ i 1)) (p 0 (+ p (if (sand?) 1 0))))
((= i n) (exact->inexact (* 4 p (/ n))))))
这种收敛非常缓慢;经过十万次迭代后,我得到了3.14188。博客文章还讨论了一种估算阿基米德在基督之前200多年开发的快速收敛的方法,其中27次迭代将我们带到了双精度算术的界限。
答案 2 :(得分:0)
这是执行monte-carlo的一般方法,它接受迭代次数作为参数,并且thunk(没有参数的过程)应该返回#t或#f,这是每次迭代运行的实验
(define (monte-carlo trials experiment)
(define (iter trials-remaining trials-passed)
(cond ((= trials-remaining 0)
(/ trials-passed trials))
((experiment)
(iter (- trials-remaining 1) (+ trials-passed 1)))
(else
(iter (- trials-remaining 1) trials-passed))))
(iter trials 0))
现在它只是编写特定实验的主要内容
您可以在实验中写下在monte-carlo中调用实验的地方,但这里的抽象可以为您提供更加灵活和易于理解的功能。如果你让一个函数一次做太多事情就很难推理和调试。
(define (marble-experiment)
(let ((x ...) ;;assuming you can come up with
(y ...)) ;;a way to get a random x between 0 and 1
;;with sufficient granularity for your estimate)
(< (sqrt (+ (* x x) (* y y))) 1)))
(define pi-estimate
(* 4 (monte-carlo 1000 marble-experiment)))