蒙特卡罗Pi计算中的基本逻辑误差



我是编程新手,决定接受使用python进行蒙特卡洛模拟来近似π值的挑战,下面是我的代码,但即使在1000000次模拟之后,它也能很好地近似π。我试图解决这个问题的方式有根本缺陷吗?

import math as m
import random
inside_circle = 0
def function(x):
return m.sqrt(1-(x**2))
def satisfied(x,y):
global inside_circle
if y < function(x) or y == function(x):
inside_circle += 1
else:
pass
l1 = []
w1 = []
for i in range(1500000):
l = [random.random() for _ in range(-1, 1)][0]
l1.append(l)
w = [random.random() for _ in range(0, 1)][0]
w1.append(w)
satisfied(l,w)
print(inside_circle/1500000*4)

您的随机采样并不是您所认为的,并且您想要

l = 1-2*random.random()
...
w = random.random()

根据二项式分布方差,自p = pi/4以来,您的方法的pi的统计不确定性为sqrt(pi(4-pi)/N)。对于与.0016有关的N=1e6事件。在进行了10次更改的情况下运行您的代码,我得到了0.0013的标准偏差,这与您所期望的差不多。

你的方法没有缺陷,并且观察到的与圆周率的差异是可以预测的。

我的意思是,首先应该更好地组织和简化代码。像

[random.random() for _ in range(-1, 1)][0]

本质上只是调用random.random((,对吧?

还要尽量避免使用那些操纵全局变量的函数,因为这些函数可能会产生恶劣的副作用,所以除非你绝对需要它们,否则请尝试其他方法。

例如,你可以将所有的东西包装在一个函数中:

def simulation(number_of_runs):
inside = 0
for i in range(number_of_runs)
x = random.random()
y = random.random()        
if is_in_circle(x,y):
inside+=1
return inside/number_of_runs*4

现在你需要一个进行检查的函数(你把这个函数放在模拟函数之前(:

def is_in_circle(x,y):
if [condition]:
return True
else:
return False

无需操作任何全局变量。现在圆的条件是X²+Y²=R(基本上是勾股定理(。在您的情况下,R=1,因此您尝试了Y=sqrt(1-X²(。然而,你不需要复杂的:

if y < function(x) or y == function(x):

Python能够执行<=选项虽然我(用你的代码(运行了这个问题,它输出了完美的3.141912,但你的问题到底是关于什么的?

所以,你的逻辑中似乎没有根本错误。你猜0和1之间的随机数,通过检查圆的条件来查看它们是否在圆内。你把圆内的点数除以尝试的总数,因为这只是圆的一个象限,你乘以4得到π。就我所见,这似乎奏效了。

最新更新