r = [ran.random() for i in range(1,100)]
s = sum(r)
r = [ i/s for i in r ]
或者,按照@TomKealy的建议,将总和和创建保持在一个循环中:
rs = []
s = 0
for i in range(100):
r = ran.random()
s += r
rs.append(r)
要获得最快的性能,请使用numpy:
import numpy as np
a = np.random.random(100)
a /= a.sum()
对于概率分布,可以给随机数任何分布:
a = np.random.normal(size=100)
a /= a.sum()
----时间----
In [52]: %%timeit
...: r = [ran.random() for i in range(1,100)]
...: s = sum(r)
...: r = [ i/s for i in r ]
....:
1000 loops, best of 3: 231 µs per loop
In [53]: %%timeit
....: rs = []
....: s = 0
....: for i in range(100):
....: r = ran.random()
....: s += r
....: rs.append(r)
....:
10000 loops, best of 3: 39.9 µs per loop
In [54]: %%timeit
....: a = np.random.random(100)
....: a /= a.sum()
....:
10000 loops, best of 3: 21.8 µs per loop
最好的方法是简单地列出你想要的数字,然后把它们全部除以和。它们完全是随机的。
或者,按照@TomKealy的建议,将总和和创建保持在一个循环中:
要获得最快的性能,请使用
numpy
:对于概率分布,可以给随机数任何分布:
----时间----
最简单的解决方法就是取N个随机值除以和。
一个更通用的解决方案是使用Dirichlet分布 http://en.wikipedia.org/wiki/Dirichlet_distribution 在纽比有售。
通过改变分布的参数,你可以改变个别数字的“随机性”
根据主参数的不同,Dirichlet分布要么给出所有值都接近1的向量,要么给出向量的长度N,要么给出向量的大多数值都是~0的向量,其中只有一个1,要么给出介于这些可能性之间的某个值。
编辑(原始答案5年后):关于Dirichlet分布的另一个有用的事实是,如果生成一个Gamma分布的随机变量集,然后将它们除以它们的和,自然会得到它。
将每个数字除以总数可能无法得到所需的分布。例如,对于两个数字,对x,y=random.random(),random.random()在正方形0<;=x<;1,0<;=y<;1上均匀地拾取一个点。除以从(x,y)到原点的直线x+y=1上的点“投影”之和。接近(0.5,0.5)的点比接近(0.1,0.9)的点可能性大得多。
对于两个变量,x=random.random(),y=1-x沿几何线段给出均匀分布。
使用3个变量,可以在立方体中拾取一个随机点并进行投影(径向投影,穿过原点),但是三角形中心附近的点比顶点附近的点更有可能。结果点位于x+y+z平面上的三角形上。如果需要在三角形中无偏地选择点,缩放就不好。
这个问题在n维变得复杂,但你可以得到一个低精度(但高精度,为所有你的实验室科学爱好者!)从所有n个非负整数的n元组集合中均匀地选取n个整数,然后将每个整数除以n
我最近想出了一个算法来处理中等大小的n,n。它应该对n=100和n=1000000有效,从而给出6位数的随机数。请看我的答案:
Create constrained random numbers?
相关问题 更多 >
编程相关推荐