用于无锁跳过列表实现的c程序中的概率随机数

时间:2017-05-29 07:01:34

标签: c

我想生成一个随机数,其中每个较高的数字都是其前任的概率的一半,如果1出现4次2应该出现2次,3次应该出现一次等等 编程语言必须是c

int getValue(int min,int max) {
    int i=0;
    while(i==0)
        i=rand()%max;
    int j=0;
    while(j==0) {
        printf("%d",j);
        j=rand()%i;
    }
    return j;
} 

3 个答案:

答案 0 :(得分:1)

可以使用以下功能:

int prioritizdRand(int min, int max)
{

    int result=min;
    int randNum=rand();
    long int start=RAND_MAX/2;

    while(randNum > start)
    {
        if(result> max )
        {
           return min;
        }
        result++;
        start= (start + RAND_MAX)/2;
    }

    return result;
}

答案 1 :(得分:1)

我首先规范化请求的范围(稍后只需将min添加到随机生成的数字中):

int max_rnd = max - min;

然后在1pow(2, max_rnd+1) - 1

范围内生成一个均匀分布的随机数
int rnd_limit = (1 << (max_rnd + 1)) - 1;
int rnd = (rand() % rnd_limit) + 1;

舍入生成的随机数的基数2对数。 rnd的翻译将遵循以下模式:

floor(log2(1)) -> 0
floor(log2(2)) -> 1
floor(log2(3)) -> 1
floor(log2(4)) -> 2
...
floor(log2(7)) -> 2
floor(log2(8)) -> 3
...
floor(log2(15)) -> 3
...

因此,结果的分布将与预期相反(对于更高的数字,则为两倍而不是一半),但这很容易改变。实际上,floor(log2(rnd))计算rnd中最高1位的位置,因此可以使用bitshift循环来实现:

int log2_rnd = 0;
while ((rnd >> log2_rnd) != 1)
{
    ++log2_rnd;
}

实际结果的时间:

return (max_rnd - log2_rnd) + min;

此处未涉及:&#34;同等分布的准确性&#34;由rand()生成的数字(特别是与模数结合使用)和生成数字的上限。

答案 2 :(得分:1)

一个简单的想法:从值1开始,取一个随机数,加一个 如果随机数为奇数,则将值右移,重复

unsigned randhalf()
{
    unsigned ret = 1;
    int rnd = rand();
    while (rnd&1)
    {
        ++ret;
        rnd >>= 1;
    }
    return ret;
}

或者如果需要上限和下限:

int randhalf(int min, int max) // bounds are inclusive
{
    int ret = min;
    int rnd = rand();
    while (rnd&1 && ret<max)
    {
        ++ret;
        rnd >>= 1;
    }
    return ret;
}

这将仅提供大于min的值但是多少位 rand()使用。