Algorithm 将数字表示为0..maxSummand中N个数字的均匀随机和
可以有无限种方式将正数表示为Algorithm 将数字表示为0..maxSummand中N个数字的均匀随机和,algorithm,random,Algorithm,Random,可以有无限种方式将正数表示为numberofsummandpositive summand的总和,每个总和不超过maxSummand。我需要一种方法来为给定的sum、numberOfSummands和maxSummand大致统一地生成其中一种表示,即,任何可能的N个summands列表都可以以大致相等的概率返回(只要双浮点精度允许) 例如: asSummands(sum = 41.0, numberOfSummands = 3, maxSummand = 22.0, prng = somePRN
numberofsummand
positive summand的总和,每个总和不超过maxSummand
。我需要一种方法来为给定的sum
、numberOfSummands
和maxSummand
大致统一地生成其中一种表示,即,任何可能的N个summands列表都可以以大致相等的概率返回(只要双浮点精度允许)
例如:
asSummands(sum = 41.0, numberOfSummands = 3, maxSummand = 22.0, prng = somePRNG())
可以返回:
[18.3, 5.8, 16.9]
(在实际生成的列表中,点后面肯定会有更多的数字。)
我可以忽略这样一个事实,即不可能使用某些求和函数达到某个求和函数(例如,如果maxSummand
为2.0,则无法使用4个求和函数达到10.0的求和函数),假设从未使用此类参数调用算法
我还假设PRNG统一生成数字
我只能想出一个远非统一的解决方案:
将总和切分为
numberOfSummands
equal summands,挑选其中的几对,并为每一对,将一个随机数从一个对元素转移到另一个元素,这样总的总和就不会改变,然后将总和洗牌。它适用于偶数个求和数,我可以修改它以适用于奇数个求和数,但解决方案感觉相当愚蠢,我觉得可能有一种更自然的方法。好的,您可能可以使用Dirichlet分布,link。在最简单的形式中,当所有<代码> a <代码>设置为1时,它将生成一致的席,使得它们在0…1中都是一致的,并且所有的
S X_i = 1
基本上,您只需通过41
重新缩放示例,您就在这里
但是!你有附加条件,使得任何席的数量小于某个阈值(22/41,在你的情况下约0.54)
最有可能的情况是,如果总和中没有很多项,您可以在Dirichlet采样的基础上应用接受/拒绝:对点集进行采样,如果任何点小于阈值,则接受该点集。更新以包括
maxSummand
限制
对于需要求和为x的n
数字的一般情况:
n
数字n
数字总和为1.0x
n
数字Sum
x
(您的目标总和)除以sum
,得到比例
比例
您现在拥有的
n
数字总和为x
,并且没有任何数字超过maxSummand
(请注意其他潜在的投票人:关于生成一个特定数字的总和有很多问题,但我看到的那些问题在总和上没有上界,这使得问题变得不同和困难。)你如何定义“一致随机”呢这里?还有,你是专门说任意实数作为分裂,还是仅仅是整数,或者仅仅是达到固定精度水平的实数?@templatetypedef除了求和数和PRNG之外的每个参数都是实数。通过“一致随机”我的意思是,所有可能的结果都应该具有相同的概率。这不是这个问题所涉及的,它所描述的问题不同于“得到n个和x之和的随机数”@Suseika:事实上,这是一个额外的限制,即任何数字都不能超过maxSummand
。我将修改我的答案以包含该限制。它不会在0..maxSummand中生成数字,而是在0..maxSummand*scale中生成随机数@苏塞卡:没错。我这方面的假设很愚蠢。我得好好考虑一下。