首页 > 解决方案 > 使用 Monte Carlo 方法估计 pi ​​会导致比预期更大的值

问题描述

我试图通过除以正方形及其嵌入圆的面积来估计 pi,但我得到〜3.66。

有谁看到我做错了什么?

inCount=0
outCount=0
it=1000000
L=100
for i in range(it):
    xran=rnd.random()*L
    yran=rnd.random()*L
    xc=abs(0.5*L-xran)
    yc=abs(0.5*L-yran)
    r=np.sqrt((xc**2)+(yc**2))
    if r<0.5*L:
        inCount=inCount+1
    if r>0.5*L:
        outCount=outCount+1
    if r==0.5*L:
        inCount=inCount+1
        outCount=outCount+1
pigen=inCount/outCount
print('pi generated: '+np.str(pigen))

标签: pythonmathpi

解决方案


你有

pigen=inCount/outCount

它给出了半径内外的命中比例。

请注意pi/(4-pi) = 3.659792...这是您的代码当前估计的值。

你需要

pigen=4*inCount/(inCount+outCount)

这将为您提供四倍的内部命中率与总数相比,即pi.


另请注意,您的代码当前是

if r<0.5*L:
    inCount=inCount+1
if r>0.5*L:
    outCount=outCount+1
if r==0.5*L:
    inCount=inCount+1
    outCount=outCount+1

可以用elif/else简化。由于r不能既大于又小于L,所以第二个if可以变成elif。同样,如果r既不小于也不大于,L那么它必须相等,所以第三个if可以简单地变成一个else

if r<0.5*L:
    inCount=inCount+1
elif r>0.5*L:
    outCount=outCount+1
else:
    inCount=inCount+1
    outCount=outCount+1

这将防止在您的代码中r进行不必要的比较。L


您的最终代码将是

inCount=0
outCount=0
it=1000000
L=100
for i in range(it):
    xran=rnd.random()*L
    yran=rnd.random()*L
    xc=abs(0.5*L-xran)
    yc=abs(0.5*L-yran)
    r=np.sqrt((xc**2)+(yc**2))
    if r<0.5*L:
        inCount=inCount+1
    elif r>0.5*L:
        outCount=outCount+1
    else:
        inCount=inCount+1
        outCount=outCount+1
pigen=pigen=4*inCount/(inCount+outCount)
print('pi generated: '+np.str(pigen))

推荐阅读