由均匀随机数发生器1-7生产出1-10

版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a763470525/article/details/82015006

前提:假设我们拥有一个随机数发生器rand7均匀产生1-7之间随机整数,如何构造rand10均匀产生1-10之间的整数。


分析:由于rand7是均匀产生,因此由均匀分布的概念来说,产生1-7之间的概率是相同的分别是1/7,因此在该条件下,为了满足计算需要可以适当丢弃1-7之间的数字,而不会影响其他数字获取的概率。

假设:rand7由该函数生成:

//生成1-7之间的随机数
int rand7() {
	int a = 0;
	return a = rand() % 7 + 1;
}

为了获取rand10这里提出2种方法:

方法一:

第一步:将1-7数字中的7移除掉,剩下1-6分别为一半奇数一半偶数,奇偶概率相同

第二步:将1-6数据分别于1进行按位与操作,将1-6转换成0-1

第三步:4次循环,每次由1-6数字产生0-1数字,生成0-15范围数字

第四步:由于0-15生成概率相同,丢弃掉0与11-15保留1-10

下面是伪代码实现:

//将1-6数据同1进行按位与运算,将奇偶转换为0-1
int GenBit() {
	int a = 0;
	while ((a = rand7()) == 7);
	return a & 1;
}
//生成1-10随机数
int GenOneToTenNormal() {
	int x;
	do {
		x = 0;
		for (int i = 0; i < 4; i++) {
			x = x << 1 | GenBit();
		}
		count++;
	} while (x <= 0 || x > 10);
	return x;
}

方法二:

第一步:将1-7数字分别减去1变为0-6

第二步:进行2次随机数生成,组成一个二位7进制数(00-66)

第三步:将7进制数据转为10进制数据(0-48)

第四步:去掉40到48让个位数字(0-9)出现的概率相同

第五步:对0-39数据与10进行求余,得到0-9数据

第六步:对0-9进行加1操作变为1-10

下面是伪代码:

//通过7进制数据生成1-10
int GenOneToTenSmart() {
	int x = 0;
	while ((x = (rand7() - 1) * 7 + (rand7() - 1)) >= 40);
	return x % 10 + 1;
}

下面是整体测试程序:

#include "stdio.h"

int main() {	
	int i = 0;
	int resultNormal = 0;
	int resultSmart = 0;
	while (i++ < 20) {
		resultNormal = GenOneToTenNormal();
		printf("resultNormal=%d\n", resultNormal);
		resultSmart = GenOneToTenSmart();
		printf("resultSmart=%d\n", resultSmart);
	}
}

//生成1-7之间随机数
int rand7() {
	int a = 0;
	return a = rand() % 7 + 1;
}

//第一种方式获取0-1之间数据
int GenBit() {
	int a = 0;
	while ((a = rand7()) == 7);
	return a & 1;
}

//第一种方式获取1-10之间数据
int GenOneToTenNormal() {
	int x;
	do {
		x = 0;
		for (int i = 0; i < 4; i++) {
			x = x << 1 | GenBit();
		}
	} while (x <= 0 || x > 10);
	return x;
}

//第二种方式获取1-10之间数据
int GenOneToTenSmart() {
	int x = 0;
	while ((x = (rand7() - 1) * 7 + (rand7() - 1)) >= 40);
	return x % 10 + 1;
}

参考资料:

七月算法:http://www.julyedu.com/

猜你喜欢

转载自blog.csdn.net/a763470525/article/details/82015006