题目:给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数。
解题思路:假定随机生成整数1到5的函数为rand_five(),现在考虑函数rand_five()能否等概率的随机生成整数1到3,即能否通过函数rand_five()实现函数rand_three(),简单的思路是不断调用rand_five()生成整数1到3,再返回,代码如下:
int rand_three(){
int x = 0;
while (x > 3){
x = rand_five();
}
return x;
}
那么函数rand_three()是否是均匀概率生成整数1到3的呢?以数字1为例,函数rand_three()是不断调用函数rand_five(),那么第一次、第二次、...、第n次都可能生成数字1,生成1的概率为: P(x = 1) = 1/5 + (2/5) * 1/5 + (2/5)^2 * 1/5 +...。
在上式中,第二项(2/5) * 1/5的意思是第一次生成的数字不是1到3,生成的是数字4和5之间的一个,后面的每一项可以以此类推。利用等比数列的性质,得出P(x = 1) = 1/3。数字2和3同理可得,P(x = 2) = P(x = 3) = 1/3。说明函数rand_three()是以均匀概率生成整数1到3的。
通过上面的分析,我们得知:当整数a小于整数b时,函数rand_a()可以通过函数rand_b()实现,那么回到原始问题,我们假设函数rand_five()能得到某个函数rand_x(),且x大于7,由前面的函数rand_five()得到函数rand_three(),我们只要得到函数rand_x(),x大于7,就可以得到函数rand_seven()。
现在考虑公式a = rand_five() * 5 + rand_five(),因为rand_five()是随机均匀生成整数1到5的,那么a是随机均匀生成整数6到30的。题目要求是均匀生成整数1到7,我们可以取前面21个数,再利用(a - 3)/3便可以得到随机均匀生成整数1到7