布冯在python中的针模拟 [英] Buffon's needle simulation in python
问题描述
将 numpy 导入为 np导入 matplotlib.pylab 作为 pltBuffon_needle_problem 类:def __init__(self,x,y,n,m):self.x = x #针的宽度self.y = y #witdh 空间self.r = []#坐标的针的中心self.z = []#测量针的弯曲度self.n = n#no of throwsself.m = m#no 模拟self.pi_approx = []定义样本(自我):# 扔针对于我在范围内(self.n):self.r.append(np.random.uniform(0,self.y))self.z.append(np.random.uniform(0,self.x/2.0))返回 [self.r,self.z]def模拟(自我):self.samples()#米模拟对于范围内的 j(self.m):# n 扔hits = 0 #设置成功为0对于我在范围内(self.n):#命中条件如果 self.r[i]+self.z[i]>=self.y 或 self.r[i]-self.z[i] <= 0.0:命中 += 1别的:继续命中数 = 2*(self.x/self.y)*float(self.n/hits)self.pi_approx.append(hits)返回 self.pi_approxy = Buffon_needle_problem(1,2,40000,5)打印(y.simulation())
对于那些不熟悉布冯问题的人,这里是 http://mathworld.wolfram.com/BuffonsNeedleProblem.html
或
实现相同的想法(和输出)http://pythonfiddle.com/historically-accurate-buffons-needle/>
我的预期输出应该是 pi 的值,但我的代码给出了大约 4.谁能指出逻辑错误?
针的对齐方式的采样应该是均匀余弦.方法见以下链接:http://pdg.lbl.gov/2012/reviews/rpp2012-rev-monte-carlo-techniques.pdf
此外,该程序存在一些逻辑问题.这是一个工作版本.
#!/bin/python将 numpy 导入为 npdef sample_cosine():rr=2.而 rr >1.:u1=np.random.uniform(0,1.)u2=np.random.uniform(0,1.)v1=2*u1-1.rr=v1*v1+u2*u2cc=(v1*v1-u2*u2)/rr返回抄送Buffon_needle_problem 类:def __init__(self,x,y,n,m):self.x = float(x) #针的宽度self.y = float(y) #空间的宽度self.r = [] #针的中心坐标self.z = [] #针对齐的测量self.n = n #no of throwsself.m = m #模拟次数self.p = self.x/self.yself.pi_approx = []定义样本(自我):# 扔针对于我在范围内(self.n):self.r.append(np.random.uniform(0,self.y))C=sample_cosine()self.z.append(C*self.x/2.)返回 [self.r,self.z]def模拟(自我):#米模拟对于范围内的 j(self.m):self.r=[]self.z=[]self.samples()# n 扔hits = 0 #设置成功为0对于我在范围内(self.n):#命中条件如果 self.r[i]+self.z[i]>=self.y 或 self.r[i]-self.z[i]<0.:命中 += 1别的:继续est =self.p*float(self.n)/float(hits)self.pi_approx.append(est)返回 self.pi_approxy = Buffon_needle_problem(1,2,80000,5)打印(y.simulation())
import numpy as np
import matplotlib.pylab as plt
class Buffon_needle_problem:
def __init__(self,x,y,n,m):
self.x = x #width of the needle
self.y = y #witdh of the space
self.r = []#coordinated of the centre of the needle
self.z = []#measure of the alingment of the needle
self.n = n#no of throws
self.m = m#no of simulations
self.pi_approx = []
def samples(self):
# throwing the needles
for i in range(self.n):
self.r.append(np.random.uniform(0,self.y))
self.z.append(np.random.uniform(0,self.x/2.0))
return [self.r,self.z]
def simulation(self):
self.samples()
# m simulation
for j in range(self.m):
# n throw
hits = 0 #setting the succes to 0
for i in range(self.n):
#condition for a hit
if self.r[i]+self.z[i]>=self.y or self.r[i]-self.z[i] <= 0.0:
hits += 1
else:
continue
hits = 2*(self.x/self.y)*float(self.n/hits)
self.pi_approx.append(hits)
return self.pi_approx
y = Buffon_needle_problem(1,2,40000,5)
print (y.simulation())
For those who unfamiliar with Buffon's problem, here is the http://mathworld.wolfram.com/BuffonsNeedleProblem.html
or
implementing the same idea (and output) http://pythonfiddle.com/historically-accurate-buffons-needle/
My expected output should be the value of pi but my code give me around 4. Can anyone point out the logical error?
The sampling of the needle's alignment should be a uniform cosine. See the following link for the method: http://pdg.lbl.gov/2012/reviews/rpp2012-rev-monte-carlo-techniques.pdf
Also, there were a few logical problems with the program. Here is a working version.
#!/bin/python
import numpy as np
def sample_cosine():
rr=2.
while rr > 1.:
u1=np.random.uniform(0,1.)
u2=np.random.uniform(0,1.)
v1=2*u1-1.
rr=v1*v1+u2*u2
cc=(v1*v1-u2*u2)/rr
return cc
class Buffon_needle_problem:
def __init__(self,x,y,n,m):
self.x = float(x) #width of the needle
self.y = float(y) #witdh of the space
self.r = [] #coordinated of the centre of the needle
self.z = [] #measure of the alignment of the needle
self.n = n #no of throws
self.m = m #no of simulations
self.p = self.x/self.y
self.pi_approx = []
def samples(self):
# throwing the needles
for i in range(self.n):
self.r.append(np.random.uniform(0,self.y))
C=sample_cosine()
self.z.append(C*self.x/2.)
return [self.r,self.z]
def simulation(self):
# m simulation
for j in range(self.m):
self.r=[]
self.z=[]
self.samples()
# n throw
hits = 0 #setting the success to 0
for i in range(self.n):
#condition for a hit
if self.r[i]+self.z[i]>=self.y or self.r[i]-self.z[i]<0.:
hits += 1
else:
continue
est =self.p*float(self.n)/float(hits)
self.pi_approx.append(est)
return self.pi_approx
y = Buffon_needle_problem(1,2,80000,5)
print (y.simulation())
这篇关于布冯在python中的针模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!