布冯在python中的针模拟 [英] Buffon's needle simulation in python

查看:56
本文介绍了布冯在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆