随机数生成问题

给定随机生成整数15的函数,写出能随机生成整数17的函数

方法1

rand5()*5+rand5(),得到[6,30]区间内25个数等概率分布

可以只用6~26之间的21个数,映射到1~77个数

27~30怎么办?抛弃掉

int rand7()
{
    int i;
    while((i=rand5()*5+rand5())>26);
    return (i-3)/3;
}

这样生成的1~7概率均匀,只是其和不等于1

 

方法2

rand5()生成一个5进制的数

假如有3位,那么每一位生成一个rand5(),这个数就是[0,444]上的均匀分布的整数

不过遗憾7不能整除5的幂次方,这样就无法均分7

不过如果位数足够大,则遗漏的概率就会相当的小

类似问题

已知rand1()等概率返回0或者1,试写一个函数等概率返回[a,b]之间的整数

用二进制表示ab

得到a的位数,b的位数,

按位生成二进制数,如果超出了[a,b]范围则重新生成

(对于上一题,如果随机数生成器可以生成偶数范围的话,可以先构造rand1(),之后的问题即为本问题)

 

类似问题

已知rand7(),球rand10()

这可以转成第一个问题:先构造rand7()*7+rand7(),然后过滤,再平分

或者可以把rand7()先转成rand5()rand2(),然后组合

int rand10()
{
    int t1;
    int t2;
    do{
        t1=rand7();
    }while(t1>5);
    do{
        t2=rand7();
    }while(t2>2);
    return t1+5*(t2-1);
}

推广:

已知randk(),求randn()

k进制表示n,先求需要多少位,求解m

k^m-1=n
m=int(m)+1
int randn()
{
    while(sum>n)
    {
        for(i=0;i<m;++i)
            bit i of sum=randk();
    }
}

理解这类题的关键知识:

每一位等概率分布 -> 这个数在整个域上也等概率分布

一个等概率分布[a,b]的子集合(例如[a+1,b-1])同样是等概率分布,只是子集合的概率和不为1,但不影响算法实现

 

refhttp://www.cnblogs.com/youxin/p/3351213.html

原文地址:https://www.cnblogs.com/plwang1990/p/4889477.html