用rand7()构造rand10()

rand7生成7个整数,没有办法均匀的映射成10个整数,但是运行两次rand7可以生成49个数字,如果这49个数字是均匀分布的,舍去多余的9个,剩下的40个正好可以用模10运算映射到10个整数上。

代码1

view plain

  1. int i;
  2. do
  3. {
  4. i = 7 * (rand7() - 1) + rand7();  // it is now uniformly random between 1 and 49
  5. while(i > 40);      // it is now uniformly random between 1 and 40
  6. return i % 10 + 1;  // result is now uniformly random between 1 and 10

这个算法做到了从40个数字均匀映射到1到10,这个说法有些抽象,进一步形象的来说明,考虑如下的种子矩阵:

view plain

  1. int seed7[7][7] = {
  2. {1 , 2 , 3 , 4 , 5 , 6 , 7},
  3. {8 , 9 , 10, 1 , 2 , 3 , 4},
  4. {5 , 6 , 7 , 8 , 9 , 10, 1},
  5. {2 , 3 , 4 , 5 , 6 , 7 , 8},
  6. {9 , 10, 1 , 2 , 3 , 4 , 5},
  7. {6 , 7 , 8 , 9 , 10, 0 , 0},
  8. {0 , 0 , 0 , 0 , 0 , 0 , 0}
  9. };

如果用x=0...6,y=1...7,则变换i=7x+y与矩阵中每个元素位置与(x,y)唯一对应,也就是x选择行,y选择列,如果x和y都是均匀分布,那么这49个位置有相同的被选中的概率=1/49。下面这行代码实现了这个变换:

view plain

  1. i = 7 * (rand7() - 1) + rand7();

其中7*(rand7()-1)相当于选择种子矩阵中的行,第二个rand7相当于选择列,而最后的模10+1运算,就恰好生成了矩阵中每个元素的值,但是(i>40)这个循环条件把最后的9个值变为了0。因此代码1等价于在种子矩阵中做选择。

时间: 2024-10-25 01:17:31

用rand7()构造rand10()的相关文章

利用rand7()构造rand10()

题意 已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10 参考代码 int rand7() { srand((int)time(NULL)); //参考 return rand()%7 + 1; } int rand10() { int x; do { x = (rand7()-1) * 7 + rand7(); }while(x > 40); return x % 10 + 1; } 解析 要保证rand10()均匀生成1~10的随机

已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10

1.int rand7()    2.{    3.  return rand()%7+1;    4.}    5.  6.int rand10()  7.{  8.    int x=0;  9.    do  10.    {  11.        x=(rand7()-1)*7+rand7();  12.    }  13.    while(x>40);  14.    return x%10+1;  15.} 分析:要保证rand10()在整数1-10的均匀分布,可以构造一个1-1

已知rand7() 可以产生1~7的7个数(均匀概率),利用rand7()产生rand10()1~10(均匀概率)

题目:已知rand7() 可以产生1~7的7个数(均匀概率),利用rand7()产生rand10()1~10(均匀概率). 解析:首先利用rand7()产生1-5的5个数,每个数的概率为1/5,然后在这5个数的基础上再以1/2的概率加上5,这样就能以1/10的概率产生每一个数. 答案: int rand10() { int tmp1,tmp2; do { tmp1=rand7(); }while(tmp1>5); do { tmp2=rand7(); }while(tmp2>2); retur

浅析 rand7生成rand10 方法 之 思想篇(一)

[问题描写叙述] rand7是一个能生成1-7的随机数.要求利用rand7生成1-10的随机数. [算法思想] 1.组合数学方法 第1次 1 2 3 4 5 6 7 之中用rand7取一个数 第2次从 2 3 4 5 6 7 8 之中取一个数 第3次从 3 4 5 6 7 8 9 之中取一个数 第4次从 4 5 6 7 8 9 10 之中取一个数 第5次从 5 6 7 8 9 10 1 之中取一个数 第6次从 6 7 8 9 10 1 2 之中取一个数 ... 第10次从 10 1 2 3 4

[Swift]LeetCode470. 用 Rand7() 实现 Rand10() | Implement Rand10() Using Rand7()

Given a function rand7 which generates a uniform random integer in the range 1 to 7, write a function rand10 which generates a uniform random integer in the range 1 to 10. Do NOT use system's Math.random(). Example 1: Input: 1 Output: [7] Example 2:

几个随机题

1. 已知有个rand7()的函数,返回1到7随机自然数,怎样利用这个rand7()构造rand10(),随机1~10. 产生随机数的主要原则是每个数出现的概率是相等的,如果可以得到一组等概率出现的数字,那么就可以从中找到映射为1~10的方法. rand7()返回1~7的自然数,构造新的函数 (rand7()-1)*7 + rand7(),这个函数会随机产生1~49的自然数.原因是1~49中的每个数只有唯一的第一个rand7()的值和第二个rand7()的值表示,于是它们出现的概率是相等. 但是

概率题(一)

转载http://noalgo.info/414.html 概率论是计算机科学非常重要的基础学科之一,概率题也是在程序员求职过程中经常遇到的问题.以下总结若干经典的概率题,作为练习. 1. 在半径为1的圆中随机选取一点. 方法1:在x轴[-1,1],y轴[-1,1]的正方形随机选取一点,如果此点在圆内,则即为所求的点.如果不在圆内,则重新随机直到选到了为止. 方法2:从[0, 2*pi)随机选取一个角度,再在这个方向的半径上随机选取一个点.但半径上的点不能均匀选取,选取的概率要和离圆心的距离成正

470. Implement Rand10() Using Rand7() (拒绝采样Reject Sampling)

问题 已提供一个Rand7()的API可以随机生成1到7的数字,使用Rand7实现Rand10,Rand10可以随机生成1到10的数字. 思路 简单说: (1)通过(Rand N - 1) % 10 + 1的方法,可以求出Rand10,当N是10的倍数的时候. (2)用( Rand7 - 1 ) * 7 + Rand7可以随机生成1-49,记作Rand49. (3)如果可以通过Rand49计算出Rand40,即随机生成1-40,就可以通过Rand40 % 10来取得Rand10. (4)如何通过

【编程珠玑】【第一章】生成随机数、随机取样的问题

一.利用随机数函数生成随机数 问题1(<编程珠玑>习题12.1后半段): 给定一个rand(),可以产生从0到RAND_MAX的随机数,其中RAND_MAX很大(常见值:16位int能表示的最大整数32767),写出利用rand()生成[a,b]中任意整数的函数,其中a>=0, b<=RAND_MAX,且b-a<<RAND_MAX. 分析: 这是在编程工作最常见的随机函数的应用,在这里做一个起点再合适不过.把随机数区间的起点从0变为a,同时把一共RAND_MAX+1个数