关于一道随机数生成的题目

题目描述:有一个rand5()随机数生成器,可以生成1-5的随机数,且每个概率都是1/5,如何利用这一个随机数生成器均匀的生成1-7的随机数,即实现一个rand7(),每一个的概率是1/7。

这道题目第一次碰到是在英特尔的笔试题中,(顺便吐槽一下英特尔的面试,简直扯淡,什么正经问题不问就跟我介绍他们的测试做的有多好了),当时由于题目并不要求得到的7个数概率均匀,所以就简单的写了个(rand5()+rand5()-2)%7+1。回来的路上一直脑子里一直有一种想法,就是把7个(rand5()-1)相加,再对7取模+1的方式应该是可以将生成的概率平均,但是一直没有去算这个概率。

(rand5()+rand5()+rand5()+rand5()+rand5()+rand5()+rand5()-7) % 7 + 1;

第二次,滴滴的一面面试官又问了我这个问题,但是要求平均,我除了这个想法想不出来其它有可能平均但又不会可能陷入死循环的方法(生成结果,然后去掉一些结果,这样可能会死循环),但是这个方法我一时之间又算不出来各个的概率是多大。于是最后只能问面试官答案是什么了,他说是用两个rand5()相乘,如果得到了25,抛弃掉重新生成,然后对7取模加1。我当时并没有去想这种方法是否真的能保证平均,第一个看法就是,这个方法有可能陷入死循环!

回来之后,我决定要把自己想法生成各个结果的概率计算一下了:

具体的计算过程,令f[i][j]表示前i个生成器(生成0-4)的和为j(0<=i<7, 0<=j<=28)的概率,以此可以用递推式来计算概率,最后f[6][0]+f[6][7]+f[6][14]+f[6][21]+f[6][28]即为生成0的概率,生成其它的数的概率求法类似,为了保证准确率,概率用分数形式表示,而不是浮点数。

最后的结果:

第一列表示对应的数,第二列是分子,第三列为分母,可以发现最后的分母完全相同,通过对比分子,可以看出,生成0-6这7个数的概率非常接近,已经非常接近均匀分布了。

也就是说,这种方法对这道题,应该是可以作为一种很好的解决方法,而且不会产生死循环。

原文地址:https://www.cnblogs.com/caozhenhai/p/5912574.html