Buffon's needle simulation in python

后端 未结 6 1489
臣服心动
臣服心动 2021-01-27 18:47
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 =         


        
6条回答
  •  佛祖请我去吃肉
    2021-01-27 19:17

    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())
    

提交回复
热议问题