【问题标题】:Generating random numbers that sum up to N and follow a discrete distribution [closed]生成总和为 N 并遵循离散分布的随机数 [关闭]
【发布时间】:2016-02-20 19:43:30
【问题描述】:

如何从集合 (1, 2, 3, 4, 5, 6) 中生成随机数,加起来为 N 并遵循 Java 中的概率分布 (0.3, 0.25, 0.25, 0.1, 0.05, 0.05) ?

更新:我可以使用this answer 中建议的 EnumeratedIntegerDistribution,但这并没有考虑到数字加起来应该是 N。

【问题讨论】:

  • 您可以使用样本大小为 1 的 EnumeratedIntegerDistribution,并将总和(在循环中)管理到 N。当您接近 N 时,您将不得不丢弃任何导致总和的结果超过 N。
  • 我想过这个问题,但这不会弄乱边缘的概率分布吗?另一种方法是生成样本大小为 N 并选择前 m 个值加起来最接近的小于 N 的数字,然后继续删除数字,直到达到 N。
  • 我不知道答案。如果 N 足够大,它不会产生影响。如果 N=1,那么你就没有随机性。如果 N=60 并且您的运行总和=58,该怎么办?我的方法允许两个(59,然后是 60)或两个的概率。我会对正确答案是什么感兴趣。一种激进的方法是丢弃任何不和 N 相加的结果,然后从头开始重试,直到它成功为止。

标签: java random sum probability


【解决方案1】:

这是integer partitions 更常见问题的一个有趣的变体。

生成 N 的整数分区相对简单,因此您有一组整数列表,总和为 N。我的想法是您可以根据指定分布中的概率为每个此类分区分配概率。然后根据计算的每个分区概率从分区集合中采样。我相信每个分区的概率应该只是其元素概率的乘积。

该方案适用于不太大的 N - 否则分区太多。如果分区列表太大,不知道该怎么办。相比之下,60的整数分区数略少于一百万(实际上是966467)。

我认为您可以使用拒绝抽样方案:从分区列表中选择一个(以统一概率)。然后生成一个介于 0 和 1 之间的随机数,并查看该分区的计算概率。如果随机数小于计算的概率,则取该分区。否则重试;继续尝试,直到你拿下一个。

我突然想到,也许只是将每个元素的概率相乘是不正确的。这将使长分区的概率远小于短分区的概率;我不知道这是否正确。也许您可以想出一种不同的方式来为分区分配概率。

编辑:可能取每个元素概率的乘积除以最大的此类乘积(因此接受概率之一是 1,其余的更小)。

EDIT2:我认为上述方案可行,但每个分区的概率需要乘以多项式系数(即 n!/(n1!n2!...nm!) 其中 n = 分区长度和n1, ..., nm 是分区中 m 个不同元素的个数)。

但也许一个更简单的方案会起作用:在总和小于 N 时生成随机数。如果正好是 N,则返回该列表。如果不是,则随机(从列表中的任何位置)删除元素,直到总和小于 N,然后重新开始添加元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 2011-05-11
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多