用蒙特卡罗模拟法估计ci

2024-09-29 22:30:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我对下面的算法有个问题。让我困惑的是为什么x = random.random()*2 -1和{}而不是简单地x = 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)

Tags: of代码inimport算法numberforif
3条回答

这个问题的有趣之处在于,这个实现同样可以工作,并且无论您使用random.random()还是{},都会给出相同的预期答案。。。所以作者选择使用random.random()*2-1的原因与程序的功能无关。在

此代码的作者对算法的理解如下:

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

现在,刻有单位圆的正方形从(-1,-1)到(1,1)。由于random()只给你[0,1]中的一个数字,所以它需要乘以2,然后移动以在[-1,1]中选择一个随机数,这个随机数选择正方形内的随机点。在

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

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

random()为您提供一个介于0和1之间的随机浮点。在

random()*2 -1给你一个介于-1和+1之间的随机浮动。在

正如通常所解释的那样,这个算法是根据单位平方中单位圆中的点的比例来计算的,这是经过片刻思考后显而易见的,第二种方法直接给出了这个结果。在

不需要太多的思考就可以看出,只使用单位平方和单位圆的右上象限仍然会给你pi/4(尽管有可能会混淆自己并弄错,就像我在这个答案的第一个版本中所做的那样)。但这并不是那么明显。这可能是一个很好的理由,让一个教程不要这样做。在

如果您对尽可能高效地计算pi感兴趣,那么使用random()可能更有意义,并添加一条注释,说明您如何将单位平方和单位圆都除以相同的值,这样几率仍然是pi/4。但是如果你有兴趣向新手程序员展示如何设计和实现随机算法呢?也许最好还是照原样写吧。在

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

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

将使范围从-1到1。在

相关问题 更多 >

    热门问题