用固定总和选择n个数字

时间:2011-04-11 14:16:40

标签: algorithm math random probability sample

在某些代码中,我想在n中选择[0,1)个随机数,其总和为1

我是通过在[0,1)中单独选择数字并通过将每一个除以总和来对它们进行标准化来实现的:

numbers = [random() for i in range(n)]
numbers = [n/sum(numbers) for n in numbers]

我的“问题”是,我得出的分布是相当偏斜的。选择一百万个数字而不是一个数字会超过1/2。通过一些努力,我已经计算了pdf,但这并不好。

这是我为5个变量得到的奇怪的pdf:

enter image description here

您是否有一个很好的算法来选择数字,从而产生更均匀或更简单的分布?

3 个答案:

答案 0 :(得分:19)

您希望将距离从0分区为1。

从0到1选择n - 1个数字,对它们进行排序并确定它们之间的距离。

这会将空格0分区为1,这会产生偶然的大结果,但是你没有得到。

即便如此,对于较大的n值,您通常可以预期最大值也会降低,但不会像您的方法那样快。

答案 1 :(得分:6)

如果您正在寻找概率,您可能会对Dirichlet distribution感兴趣,该here用于生成总和为1的数量。还有一节介绍如何使用gamma分布{{3}}生成它们。

答案 2 :(得分:0)

另一种获得n随机数总和为1的方法:

import random


def create_norm_arr(n, remaining=1.0):
    random_numbers = []
    for _ in range(n - 1):
        r = random.random()  # get a random number in [0, 1)
        r = r * remaining
        remaining -= r
        random_numbers.append(r)
    random_numbers.append(remaining)
    return random_numbers

random_numbers = create_norm_arr(5)
print(random_numbers)
print(sum(random_numbers))

这使得更高的数字更有可能。