你可以使用 rand4() 函数来实现 rand6(),通过以下方法来实现一个均匀分布的随机数生成器。
思路
rand4() 函数生成一个范围在 [1, 4] 的随机整数,而我们需要生成一个范围在 [1, 6] 的随机整数。直接使用 rand4() 是无法直接得到 [1, 6] 范围的数字的,因此需要进行一些额外的步骤。
我们可以通过组合多个 rand4() 的结果来扩大随机数的范围,然后再将其映射到 [1, 6] 的范围内。
实现方法
- 使用 rand4() 生成两个随机数,然后将它们组合成一个范围在 [1, 16] 的数字。
- 如果生成的数字落在 [1, 6] 范围内,直接返回;否则,重新生成,直到得到 [1, 6] 范围内的数字。
#include <iostream>
#include <cstdlib> // 包含rand()和srand()
#include <ctime>
#include <vector> // 包含time()
#define COUNT 10000
// 假设有一个rand4()函数,生成[1, 4]范围内的随机数
int rand4() {
return rand() % 4 + 1;
}
// 使用rand4()实现rand6()
int rand6() {
while (true) {
// 生成[1, 16]范围内的随机数
int num = (rand4() - 1) * 4 + rand4();
// 如果落在[1, 6]范围内,直接返回
if (num <= 6) {
return num;
}
// 否则重新生成
}
}
int main() {
// 初始化随机数种子
srand(static_cast<unsigned int>(time(nullptr)));
std::vector<int> arr(7);
// 测试rand6()
for(int i=0;i<COUNT;i++) {
int num = rand6();
arr[num]++;
}
for(int i=0;i<6;i++) {
std::cout<<"number1->"<< arr[i+1] <<std::endl;
}
return 0;
}
代码解释
- 组合 rand4() 结果:
- (rand4() - 1) * 4 + rand4() 生成一个 [1, 16] 范围内的随机数。(rand4() - 1) * 4 生成 0, 4, 8, 12 四个基数,然后加上另一个 rand4() 的结果,最终得到 [1, 16] 的均匀分布。
- 过滤结果:
- 如果生成的数字在 [1, 6] 范围内,直接返回;否则,丢弃当前数字并重新生成,直到生成的数字在 [1, 6] 范围内。
rand4() 乘以 rand4()为什么不行?
使用 rand4() 乘以 rand4() 生成一个 [1, 16] 范围内的数字,是不合适的,因为这样会导致结果的分布不均匀。这是由于乘法运算对随机数的分布影响较大,具体来说,它会导致某些结果出现的概率更高,而其他结果的概率更低,从而破坏了均匀分布的特性。
- 乘法的分布特点:
- rand4() 生成的每个数(1, 2, 3, 4)的概率是均匀的,即每个数出现的概率为 1/4。
- 如果我们使用乘法来组合两个 rand4() 的结果,生成的乘积结果的分布将不再均匀。例如:
- 1 * 1 = 1,只有一种方式可以生成 1。
- 2 * 2 = 4,而 4 这个结果可以由多个组合生成(如 2 * 2, 1 * 4, 4 * 1)。
- 16 可以由唯一的组合 4 * 4 生成。
- 因此,生成的结果中,较小的值和较大的值出现的概率较低,而中间的值(如 4, 8)出现的概率较高。这种分布不均匀的特性使得使用乘法的方式不适合作为均匀分布随机数生成的方法。
- 均匀分布的需求:
- 为了生成 [1, 6] 范围内的随机数,必须保证每个数字出现的概率是相同的。
- 如果你使用乘法来生成随机数,由于不同数字的组合方式不同,最终的结果无法保证均匀分布,这样生成的 [1, 6] 数字也会不均匀,违背了随机性要求。