蒙特卡洛模拟使用圆估算pi

时间:2018-08-09 17:42:39

标签: python algorithm

我对以下算法有疑问。令我感到困惑的是为什么x = random.random()*2 -1y = random.random()*2 -1而不仅仅是x = random.random()y = random.random()?完整的代码如下:

import random

NUMBER_OF_TRIALS= 1000000
numberOfHits = 0

for i in range(NUMBER_OF_TRIALS):
    x = random.random()*2 -1
    y = random.random()*2 -1

    if x * x + y * y <=1:
         numberOfHits +=1
pi = 4* numberOfHits / NUMBER_OF_TRIALS

print("PI is", pi)

3 个答案:

答案 0 :(得分:4)

此模拟中的圆以(0,0)为中心,半径为1,所以

x = random.random() * 2 - 1
y = random.random() * 2 - 1

将范围设为-1到1。

答案 1 :(得分:3)

关于这个问题的有趣之处在于,该实现同样有效,并且无论您使用random.random()还是random.random()*2-1都可以得到相同的预期答案。因此,作者选择了使用random.random()*2-1与程序无关。

此代码的 author 对该算法的理解如下:

  • 想象一个圆刻在一个正方形上。使用单位圆,因为它最简单
  • 选择正方形内的随机点,并查看圆内还有多少点
  • 圆的面积为pi,正方形的面积为4,因此落入圆的点的比例将接近pi / 4。计算测得的比率并求解pi。

现在,刻有单位圆的正方形从(-1,-1)变为(1,1)。由于random()仅在[0,1)中为您提供一个数字,因此需要将其乘以2并移位以在[-1,1)中选择一个随机数,以选择正方形内的随机点。

如果作者使用了random(),那么他将仅在第一象限内选择点。所有象限看起来都完全相同,因此命中与未命中的比率相同,并且程序仍可以正常运行,但随后程序将 不执行上述过程,并且会更难理解。

好的代码最重要的特性之一就是它清楚地传达了作者的意图。

答案 2 :(得分:1)

random()为您提供0到1之间的随机浮动。

random()*2 -1为您提供-1和+1之间的随机浮动。

如通常解释的那样,该算法是根据单位圆中单位圆中的点的比例为pi/4来考虑的,这在片刻之后很明显,而第二个则为您提供直接。

不需要花费太多的时间即可看到仅使用单位正方形的右上象限和单位圆仍会pi/4(尽管有可能混淆自己并弄错了,就像我在此答案的第一个版本中尴尬地做的那样。但这并不是那么令人眼花obvious乱。这可能是一个足够好的理由,使本教程不这样做。

如果您对尽可能高效地计算pi感兴趣,则仅使用random()并添加一条注释说明您如何同时使用单位平方和单位圆由相同的值组成,因此赔率仍然为pi/4。但是,如果您有兴趣向新手程序员展示如何设计和实现随机算法?用编写的方式写起来可能更好。