概率论计算圆周率(π)

最近找工作看了许多面经,其中看到了重复出现多次的问题:

使用概率论计算π

因此,查找并推导了如下可两种方法,具体如下:

目录

1.投针法:

1.1实验数据

1.2Python模拟程序

2.圆周法

2.1Python模拟程序

1.投针法:

------引自百度百科:蒲丰投针问题

18世纪,布丰提出以下问题:设我们有一个以平行且等距木纹铺成的地板(如图),现在随意抛一支长度比木纹之间距离小的针,求针和其中一条木纹相交的概率。并以此概率,布丰提出的一种计算圆周率的方法——随机投针法。这就是蒲丰投针问题(又译“布丰投针问题”)。

这一方法的步骤是:l
1) 取一张白纸,在上面画上许多条间距为a的平行线。
2) 取一根长度为l(l≤a) 的针,随机地向画有平行直线的纸上掷n次,观察针与直线相交的次数,记为m。
3)计算针与直线相交的概率

令事件A=‘针与某条平行线相交’,那么针与平行线相交的情况也就上图的几种形式,设h为针重点到最近的一条平行线的距离,且线相交的角度为a,针与平行线的交点到中点的距离为k,那么明显的有:

\left\{\begin{matrix} 0<h<\frac{a}{2}\\ 0<a<180 \\k<=\frac{l}{2} {\color{Red} } \end{matrix}\right.

因此就可以得到事件A发生的条件等价于:dis <= l*sin(deg),CSDN的公式输入真是难用!具体的推导我直接手写了~~

1.1实验数据

试验者

时间

投掷次数

相交次数

圆周率估计值

Wolf

1850年

5000

2532

3.1596

Smith

1855年

3204

1218.5

3.1554

C.De Morgan

1860年

600

382.5

3.137

Fox

1884年

1030

489

3.1595

Lazzerini

1901年

3408

1808

3.1415929

Reina

1925年

2520

859

3.1795

1.2Python模拟程序
 

'''
===========================================
  @author:  renjiaxin         
  @time:    2018/8/30 0030   16:33 
===========================================
'''

import random
import math

def puf(n, l=0.6, a=1):
    '''
    :param l: 针的长度
    :param a: 横线之间的间距
    :param n: 实验的次数
    :return: 圆周率π
    '''
    # 相交次数
    m = 0
    for i in range(n):
        # 针的中点与最近的线的距离
        dis = random.uniform(0, a / 2)
        # 针与线相交的度数
        deg = random.uniform(0, math.pi)
        if dis <= (l / 2) * math.sin(deg):
            m += 1
    return (2 * l * n) / (a * m)

pi = puf(1000000)

可以看到程序求得π=3.1413088739855306,利用更大的实验次数可以得到更加精确的π值

2.圆周法

该方法利用一个正方形的内切圆,用随机数生成随机点,落在圆内的概率是圆面积与正方形面积的比。具体如下:

设圆的半径为r,面积为S0;则正方形边长d=2r,面积为S1;那么事件A=‘随机点落在圆内’的概率P(A)=S0/S1,则有:

P(A)=(pi*{r^{2}})/{(2r)^{2}}=pi/4,由此可推出:

pi=4*P(A)

2.1Python模拟程序

'''
===========================================
  @author:  renjiaxin         
  @time:    2018/8/30 0030   14:16 
===========================================
'''
import random

def pai(x):
    '''
    :param x: 实验次数
    :return: 圆周率π
    '''
    cir = 0
    for i in range(x):
        a = random.uniform(0, 1)
        b = random.uniform(0, 1)
        if a**2 + b**2 <= 1:
            cir += 1
    return 4 * cir / x

pi = pai(1000000)

可以看到程序求得π=3.14187976,利用更大的实验次数可以得到更加精确的π值

猜你喜欢

转载自blog.csdn.net/qq_15969343/article/details/82225565