我试图通过使用随机性作为概率替代的简单方法来创建Buffoon的Needle实验。 pi的值可以从等式中找到 pi = 2 * ln / th其中l =针的长度,n =针落下的次数,t =线的宽度,h =针穿过线的次数。 我假设l = t从而将我的等式减少到pi = 2 * n / h。 现在我已经制作了两个代码。 代码1:
import math, random
h = 0.0
n = 0.0
for i in range(0,10000):
a = random.random()
if a > 0.64:
h = h+1
else:
n = n+1
re = 2*(n+h)/n
print "Value of pi is ", re
err = (math.pi - re)*100/(math.pi)
print "Percentage error is ", abs(err)
现在这个运行正常并给我足够好的结果。 但是下面的代码一遍又一遍地重复相同的答案。 代码2:
import random, time, math
h=1.0
n=1.0
err = 0.0
while err < 0.1:
a = random.random()
if a > 0.64:
h = h+1
else:
n = n+1
re = 2*(n+h)/n
err = (math.pi - re)*100/(math.pi)
print "Number of attempts is ", n+h
有人可以告诉我为什么吗?
答案 0 :(得分:0)
您的while
循环条件是向后的。它应该是:
while err > 0.1:
您还应将err
设置为1.0
或高于0.1
的内容。
最后,在计算错误时,您应该使用abs
:
err = abs(math.pi - re) / (math.pi)
答案 1 :(得分:0)
您希望错误在开始时尽可能大,然后循环直到它变得足够小。使用
import sys
error = sys.float_info.max
epsilon = 0.1
while err > epsilon:
...
此外,通常差异也可能是负值,因此要获得错误,您需要使用abs来仅比较幅度。因此,我们得到一个更惯用的程序
import random, time, math
import sys
h = n = 1.0
err = sys.float_info.max
epsilon = 0.001
while err > epsilon:
a = random.random()
if a > 0.64:
h += 1
else:
n += 1
re = 2 * (n + h) / n
err = abs((math.pi - re) / math.pi)
print "Value of pi is ", re
print "Number of attempts is ", n + h
答案 2 :(得分:0)
其他人已经指出了停止标准的问题,但您的代码有一个更基本的缺陷。这是不布冯的针实验。您已经找到了一种稍微复杂的方法来计算比率2.0 / 0.64。如果你反复运行你的程序并平均结果,你会发现平均值会收敛到3.125,而不是Pi。布冯的实验是基于针头是否穿过一条平行线条中的一条,这些线条基于针头中心的位置和它落下的角度,在你的程序中都没有考虑到这一点。
如果您想要一种相对简单的蒙特卡罗方法来估计Pi,则在以(0,0)为中心的2x2平方上随机生成点,并查看这些点中有多少比例落在单位半径的内切圆内。该比例应该与两个区域的比率Pi / 4相同,因此将估计的比例乘以4给出了对Pi的合理估计。在伪代码中:
count = 0
repeat N times
x <- U(-1,1)
y <- U(-1,1)
if x^2 + y^2 <= 1
increment count
pi_est <- 4 * count / N
其中U(-1,1)
表示在-1和1之间统一生成值。