【问题标题】:Picking a random item based on probabilities根据概率选择随机项目
【发布时间】:2011-02-15 21:41:46
【问题描述】:

有一个similar question,我知道,但它让我很困惑,所以我觉得用我的方式问更容易。

所以我有一组值,正数和负数。他们越高,他们被选中的可能性就越大。
我实际上很难弄清楚如何分配概率然后随机选择一个。我猜这个数组需要先排序,但在那之后我有点迷失了。

【问题讨论】:

  • 如果您参考以前的 StackOverflow 问题,来自您或其他人,即使是说它对您没有帮助,请提供链接。 StackOverflow 上有无数问题。
  • 已修复,对此感到抱歉。
  • 即使是用于 C# 我发现 vcskicks.com/random-element.php 非常有帮助。

标签: c random probability


【解决方案1】:

“我有各种不同尺寸的咖啡。它们越大,我就越想为它们收费。实际上我很难弄清楚如何分配价格”。

这不仅仅是一个编程问题 - 您已经指定概率随着价值的增加而增加,但您没有说如何它随着价值的增加而增加。通常,咖啡店的收费与咖啡量不成正比。你不能分配与价值成比例的概率,因为你的一些价值是负的,但概率不能是负的。

听起来您需要更深入地解决问题,然后才能编写任何代码。

如果您真的不关心概率与价值的关系,除了它们按价值顺序增加之外,那么一种简单的方法是:

  • 对数组进行排序
  • 将概率 1 分配给第一个元素,将 2 分配给第二个元素,依此类推。
  • 现在,您的概率加起来不等于 1,这是个问题。因此,将每个概率除以您分配的所有概率的总和:(1 + 2 + .. + n) = n(n+1)/2。这称为“标准化”。

鉴于您的概率列表加起来为 1,重复选择一个的最简单方法通常是计算 累积概率,我将通过一个示例进行演示:

value (sorted):           -12     -3      127    1000000
assigned probability:     0.1     0.2     0.3      0.4
cumulative probability:   0.1     0.3     0.6      1.0

累积概率定义为截至该点的所有概率的总和。

现在,从您的随机数生成器中,您需要一个介于 0 和 1 之间的随机(浮点)值。如果它介于 0 和 0.1 之间,则您选择了 -12。如果它介于 0.1 和 0.3 之间,则您选择了 -3,依此类推。要确定它在哪个范围内,您可以线性遍历数组,也可以进行二分搜索。

如果需要,您可以跳过规范化步骤和浮点的使用。分配“累积概率” (1, 3, 6, 10 ...) ,但要理解实际概率是存储的整数值除以 n(n+1)/2。然后选择一个从 0 到 n(n+1)/2 - 1 的随机整数。如果它小于 1,则您选择了第一个值,否则如果小于 3,则选择第二个值,依此类推。这可能会使代码更清晰,也可能不会,而且您的 RNG 可能会或可能不会很好地从大范围中选择整数值。

请注意,您可以分配概率 (0.001, 0.002, 0.003, 0.994) 而不是 (0.1, 0.2, 0.3, 0.4),并且仍然满足“值越高,概率越高”的要求。

【讨论】:

  • 哦,是的,对不起,值越高,概率越高。一旦分配了概率,如何随机选择一个?
  • 啊哈,现在说得通了。比我能找到的任何其他解释都简单得多,非常感谢。
【解决方案2】:

一种方法可能是

  • 使所有值为正(将最小值的绝对值添加到所有值)
  • 将值标准化为总和为 1(将每个值除以值的总和)

现在你可以从生成的分布中随机化一个值

  • 在 [0,1] 上选择随机数。
  • 开始对概率求和,直到总和大于或等于随机值。选择该索引作为您的随机值。

【讨论】:

  • 这种方法的问题是最小值总是被分配为零的概率。通常使用指数函数来强制积极性
【解决方案3】:

按照史蒂夫·杰索普的建议,在你选择一个从 0 到 n(n+1)/2 - 1 的随机整数后,你可以得到三角根:(-1 + sqrt((8*x )+1))/2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 2012-02-22
    • 2019-09-13
    • 2021-04-27
    • 2016-10-31
    相关资源
    最近更新 更多