数学原理
数学定律: 可以生成等概率的范围内的随机数
证明:由于可以生成之间的等概率随机数, 可以生成之间的等概率随机数
那么可以在 中随机采样 ,
因此所构成的联合概率表为:
所以,从表中可以看到,能够均匀采样出之间的随机数
代码
根据上面公式,如果想通过生成, 可以先构造出, 这样就做到了在之间均匀随机采样
代码如下:
using namespace std;
int main() {
while(1) {
int rand_value = (rand7() - 1) * 7 + rand7();
if(rand_value >= 1 && rand_value <= 10){
cout << rand_value<< endl;
break;
}
}
return 0;
}
但是这种方法的效率偏低,因为只有采样到之间才结束,而之间的数都会被抛弃
进一步优化,之间都能够进行均匀随机采样,使用模除可以放缩到
using namespace std;
int main() {
while(1) {
int rand_value = (rand7() - 1) * 7 + rand7();
if(rand_value >= 1 && rand_value <= 40){
cout << rand_value % 10 << endl;
break;
}
}
}
这样就只有之间的数被抛弃,效率会教上者更高
进制解法
上面的解法在于数学公式的证明和实用,另外一种解法是从进制的角度来思考
首先来看,如果给定, 只能生成 之间的均匀随机数,如何构造的均匀随机数 ,这种情况就无法直接套上面的公式。
如果从二进制的角度来看,可以很容易生成之间的均匀随机数,因为可以对二进制的每一位采用随机函数。那么就可以很容易生成之间的均匀随机数
现在将题目改成给定, 希望生成的均匀随机数,那么这就是用7进制来随机生成之间的数