在C语言中生成离散均匀分布

4

我想在C语言中生成0到1之间的离散均匀分布。

通常你会期望使用:t = rand()%2,但是这种方法存在问题(似乎更低位有更高的概率,尽管我不太理解这个问题)。

我试了一个在互联网上找到的技巧:

让t1、t2成为介于0和1之间的两个不很均匀的分布,其中1的概率为p,(1-p)的概率为p。然后我们取两个随机数:

t1 : p for 1, (1-p) for 0

t2 : p for 1, (1-p) for 0

如果t1!=t2,我们有(t1,t2)=(1,0)和(t1,t2)=(0,1)的概率相同:p(1-p)。因此,我们只需重复采样,直到获得t1!=t2,并选择随机数t=t1(实际上并不重要)。以下是我的代码:

#include <time.h>
#include <stdlib.h>


int main()
{
/*
Declare variable to hold seconds on clock.
*/
int i,t1,t2,t;
time_t seconds;
seconds = time(NULL);

/*
Get value from system clock and
place in seconds variable.
*/
time(&seconds);
/*
Convert seconds to a unsigned
integer.
*/
srand((unsigned int) seconds);
/*
Output random values.
*/
    for (i =0; i < 10; ++i)
    {
        do
        {
            t1 = rand()%2;
            t2 = rand()%2;
        }
        while (t1==t2);
        t = t1;

        printf("%d\n",t);
    }
            /*printf("%d",rand()%2);
    printf("%d",rand()%2);*/

return 0;
}

我是正确还是错误?非常感谢!


你需要理解 rand 到底出了什么问题,才能明白为什么这不可能起作用(与分布无关),但基本上:不要使用 rand - user2357112
5
一个替代 rand()%2 且不会因低熵位而导致偏差的简单方法是 rand() > RAND_MAX / 2 - Cornstalks
那么,“0到1之间的离散均匀分布”是指仅有1/2概率为0,1/2概率为1吗? - Mark Adler
2个回答

2
永远不要使用rand()。使用random()或者更好的PCG系列生成器
对于任何一种方法,提供的所有位都是独立的好的位。random()提供31个随机位。使用所有这些位而不仅仅是一个。没有必要丢弃其他30个。例如:
static inline int random_bit(void)
{
    static long val;
    static int bits = 0;
    int bit;

    if (bits == 0) {
        val = random();
        bits = 31;
    }
    bit = val & 1;
    val >>= 1;
    bits--;
    return bit;
}

抱歉,我不是很理解你的解决方案。你能详细解释一下吗?非常感谢。 - Dang Manh Truong
不,其实不难。你只需要认真研究代码即可。 - Mark Adler
我会试一试。 - Dang Manh Truong

0
内置的随机数生成器rand()不能保证具有您假定的特定分布('p'和'1-p'的概率)。虽然rand() > RAND_MAX / 2更好,但它仍然可能没有特定的分布。最好使用其他方法,如这里所述。
话虽如此,如果您假设1和0的概率为'p'和'1-p',则您所做的生成均匀分布的操作在数学上看起来是正确的,每个1和0的概率为2*p*(1-p),尽管您在评论中指出不愿使用此方法。

好的,我会为此寻找另一个函数。但是如果p很大(约为0.9),那么while循环不太可能会中断(因为t1 = t2 = 1的概率为0.9 * 0.9,比它们不同时要大得多)。我只是猜测而已 :P - Dang Manh Truong
@TruongTroll,你是对的。如果假设p为1,则p(1-p)为0,循环永远不会停止。但从数学上讲,你的解决方案仍然是一个均匀随机生成器,每个结果的概率都为0 :-)。 - user1969104

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