Python中的蒙特卡罗方法

时间:2012-11-19 20:22:43

标签: python montecarlo

我一直在尝试使用Python创建一个脚本,让我生成大量的点,以便在蒙特卡罗方法中使用来计算Pi的估计值。我到目前为止的脚本是这样的:

import math
import random
random.seed()

n = 10000

for i in range(n):
    x = random.random()
    y = random.random()
    z = (x,y)

    if x**2+y**2 <= 1:
        print z
    else:
        del z

到目前为止,我能够生成我需要的所有点,但我想得到的是运行脚本以便在以后的计算中使用时产生的点数。我不是在寻找令人难以置信的精确结果,只是一个足够好的估计。任何建议都将不胜感激。

3 个答案:

答案 0 :(得分:15)

如果您正在进行任何类型的重型数值计算,请考虑学习numpy。你的问题本质上是一个单线性的numpy设置:

import numpy as np

N   = 10000
pts = np.random.random((N,2))

# Select the points according to your condition
idx = (pts**2).sum(axis=1)  < 1.0
print pts[idx], idx.sum()

,并提供:

[[ 0.61255615  0.44319463]
 [ 0.48214768  0.69960483]
 [ 0.04735956  0.18509277]
 ..., 
 [ 0.37543094  0.2858077 ]
 [ 0.43304577  0.45903071]
 [ 0.30838206  0.45977162]], 7854

最后一个数字是计算的事件数量,即半径小于一的点数。

答案 1 :(得分:2)

不确定这是否是您要查找的内容,但您可以在enumerate上运行range并获取迭代中的位置:

In [1]: for index, i in enumerate(xrange(10, 15)):
   ...:     print index + 1, i
   ...:
   ...:
1 10
2 11
3 12
4 13
5 14

在这种情况下,index + 1将表示正在创建的当前点(index本身将是在给定迭代开始时创建的点的总数)。此外,如果您使用的是Python 2.x,xrange通常更适合这些类型的迭代,因为它不会将整个列表加载到内存中,而是根据需要访问它。

答案 2 :(得分:1)

只需在循环之前添加 hits 变量,将其初始化为0,并将if语句增量命中置于其中。
最后,您可以使用 hits n 来计算PI值。

import math
import random
random.seed()

n = 10000
hits = 0  # initialize hits with 0

for i in range(n):
    x = random.random()
    y = random.random()
    z = (x,y)

    if x**2+y**2 <= 1:
        hits += 1
    else:
        del z

# use hits and n to compute PI