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

前提:假设我们拥有一个随机数发生器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/

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值