选择 n 个总和固定的数字

Posted

技术标签:

【中文标题】选择 n 个总和固定的数字【英文标题】:Choosing n numbers with fixed sum 【发布时间】:2011-08-03 02:48:29 【问题描述】:

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

我这样做是通过在[0,1) 中独立选择数字并通过将每个数字除以总和来标准化它们:

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

我的“问题”是,我得到的分布是相当倾斜的。选择一百万个数字而不是一个数字会超过1/2。经过一番努力,我计算出了 pdf,结果并不好。

这是我为 5 个变量得到的看起来很奇怪的 pdf:

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

【问题讨论】:

我不确定我是否理解,如果您将数字 1 分成一百万个随机片段,那么 不应该 超过 0.5 。如果有,那就意味着另外 999,999 必须放在另一半。 看看Random Vectors with Fixed Sum。下载链接指向一个包含 MATLAB 代码的文件和一个解释算法的文档。 Generate multiple random numbers to equal a value in python的可能重复 【参考方案1】:

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

【讨论】:

你通常需要一些分布,而不是统一的从哪里来绘制你的数字。正如工作的回答所暗示的那样,您可以使用 alpha 这篇文章有一个很好的“绘图”部分,我在其中添加了一些代码示例。我不确定参数是什么是否重要,只要它们相等?【参考方案2】:

您正在寻找从 0 到 1 的距离。

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

这会将空间划分为 0 到 1,这应该会偶尔产生您没有得到的大结果。

即便如此,对于较大的 n 值,您通常可以预期您的最大值也会降低,只是没有您的方法那么快。

【讨论】:

一个可爱的算法。你知道这可能导致什么分布吗? 除了称它为“随机分区”之外,我不知道如何引用它。我一直从事物的分区方面来看待它,而不是从段长度的分布来看。 我推导出了 cdf 1-(1-x)^n 和 pmf n(1-x)^(n-1)。与我的相比,分布接缝具有更高的小数概率(它没有接近 1/n 的峰值),因此它可能也有更多的大数。我还没有将它与 Dirichlet 分布进行比较。 这是beta分布,其中最简单的情况是n个制服的最小元素的概率分布。【参考方案3】:

另一种获取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))

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

【讨论】:

以上是关于选择 n 个总和固定的数字的主要内容,如果未能解决你的问题,请参考以下文章

生成固定一列的 Python 数组

excel表格中如何使随机数相加成一个固定值?

如何在一堆数字中找出几个数字相加等于固定值

SQL中怎么获取一组总和固定的随机数

电子表格怎么用一列的每个数都乘以一个固定的数字然后结果显示分别在另外的一行

常用正则表达式(数字字符固定格式)