无论如何,我都不是经验丰富的 C++ 用户,但有兴趣看看其他答案是否与
std::rand()/((RAND_MAX + 1u)/6) 比 1+std::rand()%6 更少偏见实际上是正确的。所以我写了一个测试程序来将这两种方法的结果制成表格(我已经很久没有写过C++了,请检查一下)。运行代码的链接位于here。也转载如下:
// Example program
#include <cstdlib>
#include <iostream>
#include <ctime>
#include <string>
int main()
{
std::srand(std::time(nullptr)); // use current time as seed for random generator
// Roll the die 6000000 times using the supposedly unbiased method and keep track of the results
int results[6] = {0,0,0,0,0,0};
// roll a 6-sided die 20 times
for (int n=0; n != 6000000; ++n) {
int x = 7;
while(x > 6)
x = 1 + std::rand()/((RAND_MAX + 1u)/6); // Note: 1+rand()%6 is biased
results[x-1]++;
}
for (int n=0; n !=6; n++) {
std::cout << results[n] << ' ';
}
std::cout << "\n";
// Roll the die 6000000 times using the supposedly biased method and keep track of the results
int results_bias[6] = {0,0,0,0,0,0};
// roll a 6-sided die 20 times
for (int n=0; n != 6000000; ++n) {
int x = 7;
while(x > 6)
x = 1 + std::rand()%6;
results_bias[x-1]++;
}
for (int n=0; n !=6; n++) {
std::cout << results_bias[n] << ' ';
}
}
然后我获取了这个输出并使用 R 中的 chisq.test 函数运行卡方检验,看看结果是否与预期的显着不同。这个 stackexchange 问题更详细地介绍了使用卡方检验来测试模具公平性:How can I test whether a die is fair?。以下是几次运行的结果:
> ?chisq.test
> unbias <- c(100150, 99658, 100319, 99342, 100418, 100113)
> bias <- c(100049, 100040, 100091, 99966, 100188, 99666 )
> chisq.test(unbias)
Chi-squared test for given probabilities
data: unbias
X-squared = 8.6168, df = 5, p-value = 0.1254
> chisq.test(bias)
Chi-squared test for given probabilities
data: bias
X-squared = 1.6034, df = 5, p-value = 0.9008
> unbias <- c(998630, 1001188, 998932, 1001048, 1000968, 999234 )
> bias <- c(1000071, 1000910, 999078, 1000080, 998786, 1001075 )
> chisq.test(unbias)
Chi-squared test for given probabilities
data: unbias
X-squared = 7.051, df = 5, p-value = 0.2169
> chisq.test(bias)
Chi-squared test for given probabilities
data: bias
X-squared = 4.319, df = 5, p-value = 0.5045
> unbias <- c(998630, 999010, 1000736, 999142, 1000631, 1001851)
> bias <- c(999803, 998651, 1000639, 1000735, 1000064,1000108)
> chisq.test(unbias)
Chi-squared test for given probabilities
data: unbias
X-squared = 7.9592, df = 5, p-value = 0.1585
> chisq.test(bias)
Chi-squared test for given probabilities
data: bias
X-squared = 2.8229, df = 5, p-value = 0.7273
在我进行的三次运行中,两种方法的 p 值始终大于用于测试显着性的典型 alpha 值 (0.05)。这意味着我们不会认为他们中的任何一个都有偏见。有趣的是,所谓的无偏方法始终具有较低的 p 值,这表明它实际上可能有更大的偏差。需要注意的是我只跑了 3 次。
更新:当我写我的答案时,康拉德鲁道夫发布了一个采用相同方法的答案,但得到的结果却截然不同。我没有评论他的答案的声誉,所以我将在这里解决它。首先,主要的是他使用的代码每次运行时都使用相同的随机数生成器种子。如果你改变种子,你实际上会得到各种各样的结果。其次,如果你不改变种子,而是改变试验次数,你也会得到各种各样的结果。尝试增加或减少一个数量级以了解我的意思。第三,在预期值不太准确的情况下,会进行一些整数截断或舍入。可能不足以产生影响,但它就在那里。
总的来说,他只是碰巧获得了正确的种子和试验次数,他可能会得到错误的结果。