使用随机数

时间:2017-10-15 04:32:58

标签: python function math montecarlo pi

遇到以下问题:

在几何中,圆周长与其直径之比称为π。 π的值可以从以下形式的无限系列估计:

π/ 4 = 1 - (1/3)+(1/5) - (1/7)+(1/9) - (1/11)+ ...... 还有另一种计算π的新方法。想象一下,你有一个2平方的飞镖板。它刻有一个单位半径圆。圆的中心与正方形的中心重合。现在想象你随机在飞镖板上投掷飞镖。然后,落入圆内的飞镖的数量与投掷的总飞镖的数量的比率与圆的面​​积与方形飞镖的面积的比率相同。单位半径的圆的面积仅为π平方单位。飞镖盘面积为4平方单位。圆的面积与正方形的面积之比为π/ 4.

为了模拟投掷飞镖,我们将使用随机数生成器。 Random模块具有几个可以使用的随机数生成函数。例如,函数uniform(a,b)返回a(包括)和b(不包括)范围内的浮点随机数。

想象一下,方形飞镖盘上有一个坐标系。右上角有坐标(1.0,1.0),左下角有坐标(-1.0,-1.0)。它的边长为2个单位,其中心(以及内切圆的中心)位于原点。

飞镖靶内的随机点可以通过其x和y坐标指定。使用随机数生成器生成这些值。我们实现这一目标的方式是:

xPos = random.uniform (-1.0, 1.0)
yPos = random.uniform (-1.0, 1.0)

要确定一个点是否在圆内,它与圆心的距离必须严格小于圆的半径。坐标(xPos,yPos)与中心的距离是math.hypot(xPos,yPos)。圆的半径是1个单位。

您将要编写的程序将被称为CalculatePI。它将具有以下结构:

import math
import random

def computePI ( numThrows ):
  ... 

def main ():
  ...

main()

你的函数main()将为给定数量的throws调用函数computePI()。函数computePI()将通过为x和y坐标生成随机数来模拟dart的投掷。您将确定该随机生成的点是否在圆圈内。您将按照投掷次数指定的次数执行此操作。您将记录飞镖在圆圈内落地的次数。该计数除以总投掷数是比率π/ 4。然后函数computePI()将返回PI的计算值。 在您的函数main()中,您想要进行实验,看看PI的准确性是否随着飞镖的投掷次数而增加。您将比较结果与math.pi给出的值。输出中的数量差异是PI的计算值减去math.pi.使用以下数量的投掷来运行您的实验 - 100,1000,10,000,100,000,1,000,000和10,000,000。您将使用这些数字作为输入参数调用函数computePI()。您的输出将类似于以下内容,即您的计算PI和差异的实际值将不同,但接近显示的值:

Computation of PI using Random Numbers 

num = 100        Calculated PI = 3.320000   Difference = +0.178407 
num = 1000       Calculated PI = 3.080000   Difference = -0.061593 
num = 10000      Calculated PI = 3.120400   Difference = -0.021193 
num = 100000     Calculated PI = 3.144720   Difference = +0.003127 
num = 1000000    Calculated PI = 3.142588   Difference = +0.000995 
num = 10000000   Calculated PI = 3.141796   Difference = +0.000204 

Difference = Calculated PI - math.pi

您的输出必须采用上述格式。投掷次数必须左对齐。计算出的π值和差值必须正确表示为六位小数。差异应该有加号或减号。阅读书中有关格式化的相关章节。

直到现在我已经完成了:

import math
import random


def computePI (numThrows):

  xPos = random.uniform (-1.0, 1.0)
  yPos = random.uniform (-1.0, 1.0)

  in_circle = 0
  throws = 0

  while (throws < numThrows):
    if math.hypot (xPos, yPos) <= 1:
      in_circle += 1
    throws += 1
  pi = (4 * in_circle) / numThrows
  return pi


def main ():

  throws = (100, 1000, 10000, 100000, 1000000, 10000000)
  for numThrows in throws[0:7]:

main ()

我在Main函数中调用ComputePI函数时遇到问题。另外如何用左缩进打印num并确保所有数字都有所需的小数空格?谢谢!

3 个答案:

答案 0 :(得分:3)

您的计划有三个主要问题:

  1. 在错误的位置生成随机数

    |

    当您输入xPos = random.uniform (-1.0, 1.0) yPos = random.uniform (-1.0, 1.0) 功能时,这些行只会执行一次。然后,您继续计算完全相同的computePI() 值,进行数百甚至数千次迭代。将这些行 放在 的while循环中。

  2. 整数算术

    hypot

    由于pi = (4 * in_circle) / numThrows in_circle都是整数,因此将使用整数运算(至少在Python 2中)执行此计算。将常量从numThrows更改为4会将其更改为浮点计算:

    4.0
  3. 不完整的pi = (4.0 * in_circle) / numThrows 功能:

    您无需使用main()元组的子集,也无法在throws循环中添加正文。试试这个:

    for

答案 1 :(得分:0)

这就是我发现的简单方法。

import random
import math
def approximate_pi():
    total_points = 0
    within_circle = 0
    for i in range (10000):
        x = random.random()
        y = random.random()
        total_points += 1
        distance = math.sqrt(x**2+y**2)
        if distance < 1:
            within_circle += 1
        if total_points % 1000 == 0:
            pi_estimate = 4 * within_circle / total_points
            yield pi_estimate

将生成的总点设置为零,并将带圆圈的点设置为零

total_points = 0
within_circle = 0

多次生成x和y的随机值。计算点到圆心或(0,0)的距离。然后,如果距离小于1,则表示该距离在圆内,因此会增加。

distance = math.sqrt(x**2+y**2)
        if distance < 1:
            within_circle += 1

现在,如果您生成了1000的倍数(1000,因为我们采用了10,000的范围,所以1000获得pi的10个值),请使用此已知的公式计算pi的估计值。估计值(pi_estmate)

if total_points % 1000 == 0:
            pi_estimate = 4 * within_circle / total_points
            yield pi_estimate
pi_estimates = list(es for es in approximate_pi())
errors = list(estimate-math.pi for estimate in approximate_pi())
print(pi_estimates)
print(errors)

输出:

估算

[3.096, 3.142, 3.1253333333333333, 3.121, 3.1384, 3.136, 3.1314285714285712, 3.133, 3.1342222222222222]

错误

[0.04240734641020705, 0.02240734641020703, 0.03307401307687341, 0.020407346410206806, 0.02320734641020694, 0.0017406797435404187, -0.009021225018364554, -0.011592653589793223, -0.016703764700904067]

希望您能理解,希望我的解释很容易理解,我是初学者,正在学习东西,如果有任何问题,请随时通知。 谢谢

答案 2 :(得分:0)

基本上,您在上面编写的语句是这样的:


import math

def find_pi(iterations):
  return sum(
    1 for _ in range(iterations) if math.hypot(
                          random.random(), random.random()) <= 1) * 4.0/iterations