可能是没吃饭就去面试了,一塌糊涂,好尴尬,生成器竟然卡壳了···,问的随机数生成器生成1、2、3的概率相等,都为1/3,问如何设计生成器,使得生成1、2、3的概率为0.5、0.3、0.2.
先整体总结一下之前的生成器的问题
1给定一个随机生成器fun(),生成0和1的概率分别为0.5,那么如何构造一个生成0和1的概率分别是0.3和0.7的随机生成器?
可以考虑将其生成的数字0,1进行组合
int fun2()
{
int n=0;
int n1=fun();
int n2=fun();
int n3=fun();
int n4=fun();
n|=n1;
n|=n2<<1;
n|=n3<<2;
n|=n4<<3;
if(n<=2)
return 0;
else if(n<10)
return 1;
else
return fun2();
}
2随机生成器生成0和1的概率分别为p和1-p,那么如何构造生成0和1为等概率的随机生成器?
同样都是是对0、1进行组合,生成00概率为p^2,生成01概率为p(1-p),生成10概率为(1-p)p,生成11概率为(1-p)^2,我们可以发现生成01和生成10概率是一样的,因此可以考虑使用这个作为生成0,1的等概率随机生成器。
int fun2()
{
int n=0;
int n1=fun();
int n2=fun();
n|=n1;
n|=n2<<1;
if(n==1)
return 0;
else if(n==2)
return 1;
else
return fun2();
}
3描述RANDOM(a,b)的过程的一种实现,它只调用RANDOM(0,1)。
注:RANDOM(0,1)以等概率输出0或者1,
要求RANDOM(a,b)以等概率输出[a,b]之间的数(整数)
解决方案:
1,取 n=b-a+1,取最小的正整数m,使得 2^m >= n
2,调用RANDOM(0,1),输出m-bit位整数N ( N >= 0 and N <= 2^m-1)
3, if N >=0 and N <= b-a
then return a+N
else 重新执行步骤 2
4随机生成器生成0和1的概率分别为p和1-p,构造一个发生器,使得它构造1、2、3、…n的概率均为1/n,要求复杂度最低。
可以想怎么生成一个序列,里面有n个独立事件,概率是相等。而且我们能够猜测到这些概率的形式为 p^x*(1-p)^y,只有当x= y时,输出的概率相等的事件才最多,我们想要复杂度最低,所以最小的序列长度要求满足 C(2x,x) >=n ,我们只需要知道x就能够知道序列要多长了。
5已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10。(其实和第一题一样一样的,第一题是二进制,这个是七进制)
如果能够得到一组等概率的数,不管是什么数,只要等概率而且个数大于10,那么问题就可以解决了。
发现(rand7()-1)*7+rand7() - 1,可以等概率的生成0到48。
呵呵,这不就得了,只要把10-48砍掉就可以了。不过这样的效率比较低。可以映射
接下来再看美团这道题,完全也可以用组合的方式,可以摇两次组合成三进制的两位
这样就有 (fun()-1) * 9 + (fun()-1) * 3 + fun() - 1 得到0~26等概事件 ,取前十个按概率分即可啦!!