我需要计算单位平方内2个随机均匀分布点之间距离的期望值。这个问题可以通过分析解决,答案大约是0.521405。我想要完成的是使用随机数生成器和带有和没有numpy的Python来提出这个数字。使用以下代码
dist=list()
random.seed()
for each in range(100000000):
x1=random.random()
x2=random.random()
y1=random.random()
y2=random.random()
dist.append(math.sqrt((x1-x2)**2+(y1-y2)**2))
print(round(sum(dist)/float(len(dist)),6))
它在我的机器上以125秒迭代 1亿次,但只有4位十进制数字是正确的。 现在,随着numpy我创建了以下代码
dist=list()
start_time = time.time()
np.random.seed()
for each in range(100000000):
x = np.array((np.random.random(),np.random.random()))
y = np.array((np.random.random(),np.random.random()))
dist.append(np.linalg.norm(x-y))
print(round(np.mean(dist),6))
并且需要 1111秒来迭代相同的1亿次次!
由于结果只有4个十进制数字正确,我尝试使用以前的版本将迭代次数增加到10亿,没有numpy。我想,因为每个浮点数都在大多数64位(我使用64位Python)该列表大约需要8 GB。 但是,该程序耗尽了 26GB 的内存,并且在列表 7.9亿件
时出现例外情况所以我正在寻求你的建议:
提前致谢!
答案 0 :(得分:4)
要回答前两个子问题,这里有一种方法可以一次性生成所有随机数,然后利用np.einsum
替换大部分np.linalg.norm
的工作(平衡差异)并沿着行总和),保持代码的其余部分。实现看起来像这样 -
N = 100000 # Edit this to change number of random points
x,y = np.random.random((2,N,2))
diffs = x-y
out = round(np.mean(np.sqrt(np.einsum('ij,ij->i',diffs,diffs))),6)
答案 1 :(得分:2)
至于内存问题,你对浮动的假设需要64位'不太正确。每个float对象(实际上,它是python中的盒装对象)将占用24个字节。您可以使用sys.getsizeof(0.0)进行检查。因此,您的程序应该需要比您估计的空间多3倍的空间,这大约是您实际经历的空间。
答案 2 :(得分:1)
假设您使用的是Python 3,我建议使用此变种而不使用numpy
:
random.seed()
dist_count = 100000000
dist_sum = 0
for _ in range(dist_count):
dx = random.random() - random.random() # x1 - x2
dy = random.random() - random.random() # y1 - y2
dist += math.sqrt( dx*dx + dy*dy )
dist_average = dist_sum / dist_count
print(round(dist_average, 6))
首先,如果我们要计算并总结它们,为什么我们应该将所有距离存储在列表中?将每个随机距离直接添加到整数变量更快。此外,我们已经知道我们创建了多少随机距离,因为这是我们在for-loop范围内指定的距离,因此我们不需要像len(dist)
或单独的计数器那样的任何距离。
此外,我们不必为每个坐标指定名称,我们只需动态计算dx
和dy
差异即可。这也有助于我们进行下一步。
将相同的值与自身相乘比将其提高到2的幂(further reading...)要快一些。因此,我们当然会将a**2
替换为a*a
。现在我们直接存储上述差异变得很有用。
最后,我们将距离总和除以计数并显示结果一次。
答案 3 :(得分:1)
嗯,return_written_record_id
在我的笔记本电脑上快一点,13.5秒对post
的15.2秒
在记忆方面它可能不会使用10亿,当前版本需要~6G
代码:
hypot