【问题标题】:N random choices according to probability根据概率的 N 个随机选择
【发布时间】:2013-08-27 19:17:41
【问题描述】:

此代码用于以一定概率获取随机数: 如果r 介于 0 和 0.8 之间,则返回 8;如果r 介于 0.8 和 1 之间,则返回 2。

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>

int main()
{
    srand(time(NULL));
    double r = rand() / (double)RAND_MAX;
    double sum = 8 + 2;
    if (r < 8 / sum) {
        printf("80% \n");
    } else {
        printf("20% \n");
    }  
}

但是如果我有两个以上的数字,比如 n,我该如何处理呢?我可以用多个 if-else 语句来处理它吗?或者还有什么?

【问题讨论】:

  • 只是感兴趣:为什么要分配 2 + 8?为什么不只有 10 个?
  • @Zaibis 为了让逻辑更清晰,也许更短并不总是更好
  • 嗯,这取决于。如果你可以有很多这样的值,循环遍历一个数组可能是最好的,或者如果这些值是由某个公式确定的,那么只是一个带有值的循环。或者,如果它是一些固定值,您可以使用一系列 if/else。我真的不明白这个问题的意义。你希望发现什么?
  • 您能否举一个您希望为您的 N 问题提供的输入(例如:[8,2])和输出(例如:[80%, 20%])的示例?您甚至不需要您给出的示例中的 if/else...
  • @Dave 我想根据权重将 rand 范围分配给多个选择,例如,如果我们有选择 :5,3,2,1 那么我想要 50% 到 5, 30% 到3, 20% 到 2, 10% 到 1

标签: c random random-sample


【解决方案1】:

简单

  1. O(n) 时间创建一个概率数组(总和为 1.0)
  2. 生成一个介于 0.0 和 1.0 之间的随机数
  3. 遍历数组,在O(n)时间:
    • 如果随机数
    • 否则按概率递减随机数并移动到下一个元素
  4. 答案是与您停止的元素对应的数字

复杂

  1. 创建一个累积概率数组并将它们存储在一个数组中,在O(n)时间(这个数组应该有递增的值)
  2. 生成一个介于 0.0 和 1.0 之间的随机数
  3. 进行二分搜索以在O(log(n)) 时间内找到最小元素,即&gt;= 随机数。
  4. 答案是与您停止的元素对应的数字

我没有包括必要的极端情况来解决。我相信你可以自己做。

【讨论】:

  • 查看@pjs 的回答以获得在O(1) 中生成并在O(n) 中设置的更复杂的解决方案
【解决方案2】:

除了 randomstring 的建议之外,您还可以考虑构建一个 Alias Table -- O(n log n) 来构建表,每个值 O(1) 来生成。

【讨论】:

  • +1 更好的答案!我今天学到了一些新东西:)希望他改变接受的答案。
猜你喜欢
  • 1970-01-01
  • 2011-02-15
  • 1970-01-01
  • 2012-02-22
  • 2011-10-20
  • 2021-04-27
  • 2013-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多