基于概率的真或假

true or false based on probability

本文关键字:概率 于概率      更新时间:2023-10-16

我对操作符有点困惑,那里使用随机生成。我想我只是想问,这段代码能按我的要求去做吗?

根据我分配的函数的概率生成一个"随机的"TRUEFALSE

bool randtf(int probability) {
    if ((rand() % 100) < probability)
        return true;
    else
        return false;
}

所以如果randtf(63),它有63%的机会是TRUE ?

任何指导将不胜感激。谢谢。

是的,一个近似。

不,更准确地说。rand()返回一个介于0RAND_MAX之间的数字,这个数字在实际中总是以(1 << n) - 1的形式出现。这不是100的倍数,所以当你取模时,你不会得到一个完美的均匀分布。

你可以通过使用拒绝抽样来解决这个问题。为了便于讨论,我们假设是RAND_MAX == 32767(即16位)。第一步是继续生成随机数,拒绝它们,直到得到一个小于32700的随机数(小于RAND_MAX的100的最大倍数)。如果你对它做模运算,你会得到一个均匀分布

当然,这假设了rand()的一个合理的、统计上健壮的实现,这是一个相当大的假设!

MAX_RAND不是100的倍数,因此您的分配在技术上是不公平的。你必须缩放rand(),而不是mod它

这取决于rand()返回的内容,特别是如果可能的数字范围是100的精确倍数(并且均匀分布)。一般来说,使用模并不一定能给出正确的统计行为。

举例来说,假设你的rand()只返回值0,1,2,3,4,5,6;你说的是rand() % 5 < p(这里是0 <= p < 5)。但是请注意:这将值0和1取两次,但是在有效的源数字范围内,2、3和4只取一次!因此,对于p = 4实际上并没有得到80%的概率,而只有1/7。

即使随机生成器是完全随机的,因为rand()只生成0到0x7FFF的数字,所以它也不能是完全分布的。考虑下面的代码:

int arr[100] = { 0 };
for( int i=0; i<0x7FFF; i++ ){
arr[ i % 100 ]++;
}
for( int i=0; i<100; i++ ){
    cout << arr[i] << endl;
}
return 0;

如果你运行这段代码,它不会给你相同的数字:

328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
328
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
327
Press any key to continue . . .