概率程序

use*_*460 5 c++ random algorithm math probability

在我们需要生成概率的情况下,例如具有 75% 的抛头和 25% 的抛尾的偏置硬币。按照惯例,我会这样做:

#include <cstdlib>
#include <iostream>
#include <ctime>
using namespace std;

int main()
{
    int heads=0, tails=0;
    srand(time(NULL));
    number = rand() % 100 + 1;  //Generate random number 1 to 100
          if (number <= 75) //75% chance
                heads++; //This is head
          else
                tails++; //This is tail
}
Run Code Online (Sandbox Code Playgroud)

这是一个可以运行的代码,但是当我为另一个用户回答关于偏置币的类似问题时,一些用户提到了 100 的倍数。由于随机函数生成均匀分布,我觉得上面的代码已经足够了用于模拟概率事件。

在过去的 SO 帖子中,用户 Bathsheba 提到了一些关于 100 的倍数的内容:用偏置硬币模拟抛硬币的程序 我想知道我的代码中与此相关的可能问题是什么。

我的问题是:上面的代码是一个可接受的代码来创建一个概率模拟吗?或者这些代码中是否有任何缺陷会影响模拟结果的准确性。如果上述代码有缺陷,那么实现概率模拟的正确方法是什么?

编辑:通过 10,000,000 次抛掷的模拟测试。它总是以大约 75.01%-75.07% 的概率产生抛头。那么当它生成看似准确的结果时会出现什么问题。(生成的结果似乎没有倾斜

4pi*_*ie0 2

上面的代码是创建概率模拟的可接受的代码吗?或者这些代码是否存在任何缺陷,会影响模拟结果的准确性?

如果这是“可接受的”,这取决于您对可接受的定义是什么。这肯定是不正确的,因为运算符 % 会使您的概率出现偏差,因为 RAND_MAX 的最大值rand()可能不等于 k ​​ 100 + 99,这会导致如果您想象 0-RAND_MAX 字符串的 100 长度部分,那么您可以请注意,最后一部分可能不会产生完整范围的 0-99,因此您有更多的数字可以生成0, 1, 2..., x但不一定是x + 1, ..., 98, 99(多出现 1 次)对于 0, 1, 2, ..., x) 中的每个数字。这种方法的不准确性随着除数的增大而增加,除数不能均匀地划分范围。

如果上述代码有缺陷,那么实现概率模拟的正确方法是什么?

您可以使用 boost 或者如果您可以运行 C++11 那么您可以使用标准库的uniform_int_distribution