【问题标题】:Random numbers with different probabilities [duplicate]具有不同概率的随机数[重复]
【发布时间】:2012-10-06 17:22:12
【问题描述】:

可能重复:
C++ function for picking from a list where each element has a distinct probability

我需要根据我可以定义的概率 (.25, .50, .75) 随机确定是或否结果(抛硬币的类型)。

例如,我想随机确定“是”或“否”,其中“是”有 75% 的机会被选中。我有什么选择?有没有我可以使用的 C++ 库?

【问题讨论】:

    标签: c++ random probability


    【解决方案1】:

    您可以使用rand 函数轻松实现此功能:

    bool TrueFalse = (rand() % 100) < 75;
    

    rand() % 100 会给你一个 0 到 100 之间的随机数,它低于 75 的概率是 75%。您可以将75 替换为您想要的任何概率。

    【讨论】:

    • +1,别忘了srand()
    • 或多或少同样可能...假设 RAND_MAX 为 32767;那么对于数字 0..67,与 68..99 相比,可以随机选择多一个值。这是否重要取决于上下文。
    • 使用 C++11 / TR1 。更容易而不是破坏分布。
    • @Luchian Grigore 精心设计是指整个应用程序只有一个状态。这在很多方面都非常糟糕,我不得不怀疑任何人甚至会考虑使用它。是的,% 1000 是一种方法,但下一步是什么? 10000? 10万?不好,这很可能比 RAND_MAX 大。真正的分布是要走的路(正如我已经说过的)。
    • 如果 RAND_MAX 为 32767,则选择值小于 75 的百分比理论上约为 75.0518% (100 * (328*68 + 327 * 7) / 32768 = 75.0518);根据经验,我测量了 75.0564%。如果 RAND_MAX 为 0x7FFFFFFF,则差异要小得多(经验上为 75.0008%;理论上为 100*(21474837*48 + 21474836*27) / 2147483648 = 75.00000056%)。如果你有 C99 最低可接受的 rand() 函数,那么会有一个明显的(有点仍然很小而且通常是微不足道的)偏差;如果您有 32 位 RAND_MAX,则偏差通常可以忽略不计。但你必须知道 RAND_MAX 是什么才能做出判断。
    【解决方案2】:

    查看 C++11 伪随机数库。

    http://en.cppreference.com/w/cpp/numeric/random

    http://en.wikipedia.org/wiki/C%2B%2B11#Extensible_random_number_facility

    std::random_device rd;
    std::uniform_int_distribution<int> distribution(1, 100);
    std::mt19937 engine(rd()); // Mersenne twister MT19937
    
    int value=distribution(engine);
    if(value > threshold) ...
    

    这样,然后说75以上都是真的,以下都是假的,或者你想要的任何阈值

    rand 不同,您实际上可以控制数字生成的属性,而且我不相信其他答案中使用的 rand(使用模数)甚至呈现均匀分布,这很糟糕。

    【讨论】:

    • 请使用真实的发行版,这样我才能投票给你。
    • @cooky451 如果它应该模仿抛硬币的制服,那么肯定是正确的分布吗?
    • 但是你不是在模拟硬币翻转(这将多次取 1 出 2),你是在一次做所有事情。下一步将是 12.5 的概率,你将如何用整数做到这一点?当然,您可以然后切换到 [1..1000] 范围,但是,真正的分布仍然是合乎逻辑的方式。
    • 其实...是的!这个更好。如果使用模数,您将在 (threshold mod 2 = 0) 时得到均匀分布,因为 C++ RAND_MAX = 2^31 - 1。或者有 2^31 个可能的值。 (加零)示例。 rand() % 5 where (suposition) RAND_MAX = 16 ***** ***** ***** *[----] p : 概率; p(rand() % 4 == 0) = 4/16 p(rand() % 4 == 1) = 3/16 p(rand() % 4 == 2) = 3/16 p(rand() % 4 == 3) = 3/16 p(rand() % 4 == 4) = 3/16
    【解决方案3】:
    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    bool yesOrNo(float probabilityOfYes) {
      return rand()%100 < (probabilityOfYes * 100);
    }
    
    int main() {
        srand((unsigned)time(0)); 
        cout<<yesOrNo(0.897);
    }
    

    如果您调用 yesOrNo(0.75),它将在 75% 的时间返回 true

    【讨论】:

    • 因为probabilityOfYesint 类型,它与yesOrNo(0) 相同并且将始终返回no。 (可能意味着它是 floatdouble
    • @amit 没错。我已经编辑了代码。
    【解决方案4】:

    std::random_deviceboost::random 如果您的 C++ 编译器未实现 std::random_device,则使用 boost::random 您可以使用 bernoulli_distribution 生成随机的 bool 值!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-11
      • 1970-01-01
      • 2017-10-01
      相关资源
      最近更新 更多