我正在尝试处理蒙特卡罗算法来计算pi的值。当我尝试提供如下程序中提到的大量输入时。我收到内存错误。我该怎么做才能纠正它?代码如下:
def PiCalc():
N_ok=0
n=1000000000000
for i in range(n):
x=random()
y=random()
if sqrt(x**2 + y**2) <= 1:
N_ok+=1
pi= 4.0 * N_ok / n
print "No. of points inside the circle: ", N_ok
print "Pi: ", pi
return pi
答案 0 :(得分:5)
在Python 2.7 range(n)
中将创建一个包含1000000000000个元素的列表,这会导致MemoryError
使用xrange(n)
您可以随时生成项目
根据文件:
xrange(开始,停止[,步骤]) 此函数与range()非常相似,但返回xrange对象而不是list。这是一个不透明的序列类型,它产生与相应列表相同的值,而不是实际同时存储它们。 xrange()在range()上的优势是最小的(因为xrange()在被要求时仍然需要创建值)
答案 1 :(得分:5)
鉴于没人提到这一点......
您也可以使用itertools.repeat(None, n)
。这将比range
和xrange
快得多,因为它不会创建一个新的int
实例。
使用repeat()
,您的for循环变为:
for _ in itertools.repeat(None, n):
x=random()
y=random()
if x**2 + y**2 <= 1:
N_ok += 1
答案 2 :(得分:2)
由于您使用print
的方式,我假设您使用的是Python 2.x.在Python 2.x中,range
返回一个列表。所以你试图在内存中建立一个1000000000000整数的列表。这里的内存错误是正常的。
你应该尝试:
for i in xrange(n):
因为xrange
返回一个xrange对象(*)并且没有在内存中构建列表。
(*)它允许迭代值,但它实际上不是迭代器(感谢DSM的精度)
答案 3 :(得分:1)
我要创建一个函数:
def random_pairs(n):
for _ in itertools.repeat(None, n):
yield random(), random()
N = sum(1 for (x, y) in random_pairs(n)
if x**2 + y**2 <= 1.)