我在这个计算 PI 的方案程序中找不到错误
我正在做蒙特卡罗实验来计算 PI 的近似值。来自 SICP:
蒙特卡罗方法包括 随机选择样本实验 从一个大集合然后制作 的基础上扣除 估计的概率 将这些结果制成表格 实验。例如,我们可以 使用以下事实进行近似 6/pi^2 是两个概率 随机选择的整数将没有 共同因素;也就是说,他们的 最大公约数为 1。 获得 的近似值,我们 进行大量实验。 在每个实验中我们选择两个 随机整数并执行测试 看看他们的 GCD 是否为 1。分数 测试通过的次数给出 我们估计 6/pi^2,并且来自 我们得到了我们的近似值 圆周率。
但是当我运行我的程序时,我获得像 3.9 这样的值...
这是我的程序:
(define (calculate-pi trials)
(define (this-time-have-common-factors?)
(define (get-rand)
(+ (random 9999999999999999999999999999999) 1))
(= (gcd (get-rand) (get-rand)) 1))
(define (execute-experiment n-times acc)
(if (> n-times 0)
(if (this-time-have-common-factors?)
(execute-experiment (- n-times 1) acc)
(execute-experiment (- n-times 1) (+ acc 1)))
acc))
(define n-success (execute-experiment trials 0))
(define prob (/ n-success trials))
(sqrt (/ 6 prob)))
我的解释器是 MIT/GNU 7.7.90
感谢您的帮助。
I am doing a Monte Carlo experiment to calculate an approximation of PI. From SICP:
The Monte Carlo method consists of
choosing sample experiments at random
from a large set and then making
deductions on the basis of the
probabilities estimated from
tabulating the results of those
experiments. For example, we can
approximate using the fact that
6/pi^2 is the probability that two
integers chosen at random will have no
factors in common; that is, that their
greatest common divisor will be 1. To
obtain the approximation to , we
perform a large number of experiments.
In each experiment we choose two
integers at random and perform a test
to see if their GCD is 1. The fraction
of times that the test is passed gives
us our estimate of 6/pi^2, and from
this we obtain our approximation to
pi.
But when I run my program I obtain values like 3.9...
Here is my program:
(define (calculate-pi trials)
(define (this-time-have-common-factors?)
(define (get-rand)
(+ (random 9999999999999999999999999999999) 1))
(= (gcd (get-rand) (get-rand)) 1))
(define (execute-experiment n-times acc)
(if (> n-times 0)
(if (this-time-have-common-factors?)
(execute-experiment (- n-times 1) acc)
(execute-experiment (- n-times 1) (+ acc 1)))
acc))
(define n-success (execute-experiment trials 0))
(define prob (/ n-success trials))
(sqrt (/ 6 prob)))
My interpreter is MIT/GNU 7.7.90
Thanks for any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,为了直接回答你的问题,你可以把 if 语句倒过来;应该是这样的。
因此,当试验次数接近无穷大时,您将在极限范围内计算 1 - 6/π2。得出 "pi" = sqrt(6/(1 - 6/π2)) = sqrt(6π2/(π2- 6)) = 3.911)。
不过,让我们退后一步,看看蒙特卡罗方法通过此计算为我们做了什么(提示:预计收敛速度会非常慢。您运行了多少次?)...
每次试验要么给我们 0 要么1,概率 p = 6/π2。这是伯努利过程的一个示例,对于 1 的数量 m 在许多试验n中,二项式分布 。
考虑 ρ = m/n,即通过公约数测试的次数分数。该 a 的平均值为 p,方差为 p(1-p)/n,或 std dev σρ = sqrt(p(1-p)/n)。对于 n = 10000,标准差应该为 0.00488。 95% 的时间您将处于平均值的 2 标准差以内,5%有时您将处于 2 标准开发之外,或介于 0.5982 和 0.6177 之间。因此,在 n=10000 的情况下,通过此方法估算的 π 95% 的时间将在 3.117 到 3.167 之间,5% 的时间在此范围之外。
如果您想将试验次数增加 100 次,那么标准差就会减少 10 倍,并且 π 的估计值会缩小到 3.1391 到 3.1441 之间,置信度为 95%。
蒙特卡罗方法非常适合粗略估计,但需要大量试验才能获得准确答案,并且通常会达到收益递减的程度。
这并不是说这是一种徒劳的近似 pi 的方法,只是要注意这个问题。
Well, to answer your question directly, you have the if-statement backwards; it should be this way.
So you're calculating 1 - 6/π2 in the limit as the # of trials approaches infinity. This yields "pi" = sqrt(6/(1 - 6/π2)) = sqrt(6π2/(π2-6)) = 3.911).
Let's take a step back here, though, and look at what the Monte Carlo method does for us with this calculation (hint: expect very slow convergence. How many times are you running it?)...
Each trial either gives us 0 or 1, with probability p = 6/π2. This is an example of a Bernoulli process, which has, for the number of 1's m in a number of trials n, a binomial distribution.
Consider ρ = m/n, the fraction of times passing the common-divisors test. This a has mean value of p and a variance of p(1-p)/n, or std dev σρ = sqrt(p(1-p)/n). For n = 10000, you should expect a std dev of 0.00488. 95% of the time you will be within 2 std devs of the mean, and 5% of the time you'll be outside 2 std devs, or between 0.5982 and 0.6177. So an estimate of π from this method, given n=10000, will be between 3.117 and 3.167 95% of the time and outside this range 5% of the time.
If you want increase the number of trials by 100, that reduces std dev by a factor of 10 and the estimate of π gets narrowed between 3.1391 and 3.1441 with 95% confidence.
Monte Carlo methods are nice for a rough estimate but they need LOTS and lots of trials for an accurate answer, and usually reach a point of diminishing returns.
Not that this is a fruitless way to approximate pi, just be aware of the issue.
我发现我的错误。
感谢大家。
我在错误的地方增加了成功的案例。
更正后的代码为:
I find my error.
Thanks to all.
I was incrementing the successful cases in the wrong place.
The corrected code is: