【问题标题】:Represent a number as a uniformly random sum of N numbers in 0..maxSummand将一个数字表示为 0..maxSummand 中 N 个数字的均匀随机总和
【发布时间】:2016-01-03 22:25:52
【问题描述】:

可以有无数种方法将正数表示为numberOfSummands 正数之和,每个正数不超过maxSummand。我需要一种方法来为给定的sumnumberOfSummandsmaxSummand 大致一致地生成其中一个表示,即可以以大致相等的概率返回任何可能的 N 加法列表(只要双浮点精度允许它)。

例子:

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相等的和数,选择它们的对,对于每一对,将随机量从对的一个元素转移到另一个元素,这样总和不会改变,然后将号令。它适用于偶数个被加数,我可以修改它以适用于奇数个被和数,但解决方案感觉很愚蠢,我觉得可以有更自然的方法。

【问题讨论】:

  • (注意其他可能接近的选民:有很多关于生成总和为特定数字的数字的问题,但我查看的那些在summands,这使问题变得不同且更难。)
  • 这里如何定义“均匀随机”?另外,您是专门讨论作为分割的任意实数,还是整数,或者只是达到固定精度水平的实数?
  • @templatetypedef 除和数和 PRNG 之外的每个参数都是实数。我所说的“均匀随机”是指所有可能的结果都应该具有相同的概率。

标签: algorithm random


【解决方案1】:

好的,您可能可以通过 Dirichlet 分发来做到这一点,链接 https://en.wikipedia.org/wiki/Dirichlet_distribution。在最简单的形式中,当所有a 都设置为 1 时,它将生成统一的 Xi 使得它们在 [0...1] 中都是统一的,并且所有的总和

S X_i = 1

基本上,您只需通过 41 重新调整您的示例,您就在这里。

但是!您还有其他条件,即任何 Xi 都应小于某个阈值(22/41,在您的情况下约为 0.54)

如果您的总和中没有很多项,最有可能的是,您可以在 Dirichlet 采样之上应用接受/拒绝:对一组点进行采样并在任何点小于阈值时接受它。

【讨论】:

    【解决方案2】:

    更新为包含maxSummand 限制。

    对于您希望 n 数字总和为 x 的一般情况:

    1. 生成介于 0 和 1 之间的 n 数字。
    2. 求和。
    3. 将每个数字除以总和。您现在拥有的 n 数字总和为 1.0。
    4. 将每个数字乘以x

    如果对最大和数有限制,可以这样修改算法:

    1. 生成介于 0 和 maxSummand 之间的 n 数字。
    2. 将它们相加,得到sum
    3. x(您的目标总和)除以sum,得到scale
    4. 将每个生成的数字乘以scale

    您现在拥有的 n 数字总和为 x,没有超过 maxSummand 的数字。

    【讨论】:

    • 这不是这个问题的内容,它描述的问题与“获取n个总和为x的随机数”不同。
    • @Suseika:实际上,它,附加限制是任何数量都不能超过maxSummand。我将修改我的答案以包含该限制。
    • 不会在0..maxSummand中生成数字,会在0..(maxSummand*scale)中生成随机数
    • @Suseika:确实如此。我的愚蠢假设。我得再考虑一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 2014-12-29
    • 2012-04-11
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多