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