C语言中的带偏差的随机数生成器函数

4
尝试在C语言中创建以下函数:
bool randBool(double bias)

该函数随机返回01

让我困惑的是,我希望允许用户在范围[-1.0, 1.0]内输入"偏差",表示输出为01的可能性。

以下是一些示例,说明输入的偏差应如何影响函数:

=======================================================

randBool(-1.0)应始终返回0

randBool(1.0)应始终返回1

randBool(-0.5)比返回1更有可能返回0

randBool(0.05)比返回0更有可能返回1

randBool(0.0)返回01的概率相等。

=======================================================

我几乎可以确定这是一个概率问题,但我对此并不熟悉,所以我不知道如何实现这个函数。


@mch:这里不必要地在整数上使用了浮点函数,将 RAND_MAX 映射为零(因为除数是 RAND_MAX 而不是 RAND_MAX+1),没有将 fmod 的结果缩放到 -1 到 1(或者反过来,缩放偏差与 fmod 的结果相匹配)。 - Eric Postpischil
2
请明确一下,当您说0的概率增加了50%时,是指P(0)=75%,P(1)=25%,即概率之间有50%的绝对差异,但您会得到三倍于1的0,还是P(0)=60%,P(1)=40%,其中P(0)是P(1)的150%,即相对差异为50%,因此您将获得比1多50%的0?(我猜测是第一个,因为这与您的“应该100%返回0/1”的示例一致。) - Rup
1个回答

5

类似这样的:

bool randBool(double bias) {
    return rand() < ((RAND_MAX + 1.0) * ((bias + 1) / 2));
}

该公式中的((bias + 1) / 2)是为了将偏差值从[-1,1]范围转换到[0,1]范围内。如果bias参数已经在[0,1]范围内,则可以避免这种情况。

偏差被定义为返回1的概率。具体如下:

  • 0.0(对应偏差-1.0):全部为0
  • 0.25(对应偏差-0.5):25%的1和75%的0
  • 0.5(对应偏差0.0):1和0的数量相等
  • 0.525(对应偏差0.05):52.5%的1和47.5%的0
  • 1.0(对应偏差1.0):全部为1


RAND_MAX相关注释

  • 如果RAND_MAX < INT_MAX,则可以使用RAND_MAX + 1代替RAND_MAX + 1.0

  • 如果RAND_MAX + 1.0不能被double精确表示(参见Are all integer values perfectly represented as doubles?),则该解决方案不可靠。
    在这种平台下的一种方法是,将rand()的结果重新缩放到可以由intdouble表示的范围内(取决于您使用RAND_MAX + 1还是RAND_MAX + 1.0)。
    或者,使用另一个随机数生成器(没有这个问题),这可能是个好主意,因为目前有许多低质量的rand()实现。


谢谢!这正是我需要的。我还意识到,对于我将要使用的输入,[0,1]范围更适用。 - Oh Fiveight
1
也许是 RAND_MAX + 1.0?当然,如果有保证 RAND_MAX < INT_MAX 的话就不用了。 - pmg
1
@pmg:当然,也不能保证RAND_MAX小于将1添加到double产生比返回相同的double多1的点,而不是由于舍入而返回相同的double。在具有64位int和常见的IEEE-754 64位double的C实现中,RAND_MAX可能超过2^53,在此之后,double中的整数值会受到舍入的影响。 - Eric Postpischil
@EricPostpischil:我已经添加了一些注释到我的答案中来涵盖这个问题。感谢您指出! - Sander De Dycker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接