【问题描写叙述】

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 5 6 之中用取一个数
1-10每一个数字在上表中都出现了7次。共同拥有70个数字,这样每一个数字被命中的概率为1/10。
这里的关键词是"命中".
第11次又一次循环,从 1 2 3 4 5 6 7 之中取一个数
第12次从 2 3 4 5 6 7 8 之中取一个数
......
依照这种方法。1-10每一个数字被命中的概率是均匀分布。而1-10次的数组,本质上是生成了全部1-10依照次序的一个轮换结构。也就是组合问题中的生成全部排列。(參见Knuth第4卷第2冊(The Art Of Computer Programming, Volume4, Generating
All Tuples and Permutations))在经过比較长的时间之后,就能够观察到均匀分布。其实,不论什么随机数算法都须要经过比較长的过程才干观察出他的分布。而概率分布。是在一个统计意义上的概念。
由此还能够得出用m个随机数生成n个随机数的方法
1. 当m > n的时候,用舍去法,每次n个随机数,超过这个范围就舍弃,再来一次。
2. 当m < n的时候,用如上的方法建立m大小的数组,当中的数字在1到n依照次序循环轮换,这样n*m个循环之后。就能够得到均匀的n个随机数。


2. 同余循环法

上面这种方法。实际上等价于(rand7() + i)%10。i从0-9重复循环。而每次计算的余数恰好与上面的方法等价。也就是用利用同余的性质生成全部排列。这真是一个巧妙的想法!

于是:

1. i从0到9重复循环
2. (rand7()+i)%10,产生0-9的随机数。等效与第一种组合法(仅仅须要把上面表中的1-10改成0-9)
3. 再+1得到1-10的随机数

优化后仅仅须要一行代码!


于是上面用m个随机数生成n个随机数的方法的,也有了更简洁的算法,步骤与此相似就不写了。


3. 舍去法

这个题在考试中大概是不让用舍去法的,由于他太平庸。

但实际上舍入法也非常实用。因此还是写出来,后面还会再提到舍入法。

1. 第一次用rand7取出1到5的随机数,记为a
2. 第二次用rand7取出1或2,记为b
3. 假设b = 1, 则c = a, 假设b = 2,则c = a + b
4. 返回c

4. . 连续随机变量的分布
本题的rand7是一个离散随机变量,仅仅取1-7的整数。

离散变量的缺点是在数学计算上不方便,因此能够转成连续随机变量。也就是从rand7生成1-7的连续均匀分布,获得1-10的均匀分布。尽管本题不适用这种方法,可是本题除了考试实用,在实际应用中不会出现,很多其它的方法是从一种分布变换到第二种分布。

如今的答案非常easy。从几何的角度上看,我们能够把[a,b]线段上的点依照一对一映射到还有一个线段[c,d]上去,仅仅须要做一个线性变换y=(x-a)/(b-a)*(d-c)+c. 那么。若rand()~U(a,b),则y=(rand()-a)/(b-a)*(d-c)+c~U(c,d)。也就是假设rand()是a到b上的均匀分布,则y=(d-c)(x-a)/(b-a)+c是c到d上的均匀分布。

对于本例rand10=(rand()-1)/6*9+1. 
这个定理还能够更强一些,f(x)是分段还是也能够。甚至仅仅是一个覆盖(包含)就能够了。从符合一种分布的随机数生成第二种分布的随机数是统计模拟的课题,当中有非常有趣的变换方法,比如,假设X是(0,1)上的均匀分布,则Y=-a*log(X)是指数分布。这些内容,參考《统计判断》,或者更进一步的材料。

5. 再谈舍入法
C语言的rand函数,可能是用了线性同余算法获得均匀分布,这类叫直接方法。舍去法也是非常重要的一类随机,用来生成各种分布的随机数,比方Metropolis算法。比較著名的还有Markov Chain Monte Carlo (MCMC)算法。这类方法能够看成是一个黑盒子。要求在算法内部通过几次运算非常快收敛到一种概率分布,然后返回一个随机数。參见Casella & Berger统计判断(Statistical
Inference)以及Kunth第2卷Seminumerical Algorithms, Random Numbers.

浅析 rand7生成rand10 方法 之 思想篇(一)的更多相关文章

  1. rand7生成rand10,rand1生成rand6,rand2生成rand5(包含了rand2生成rand3)

    这种题要分两步,第一步是“插空儿”,第二步是“筛” 1.rand7生成rand10 只要是10的倍数就好 int rand10() { int num; do{ num = (rand7() - ) ...

  2. 随机数范围扩展(如rand7()到rand10())(转)

    题目:已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10.分析:要保证rand10()在整数1-10的均匀分布,可以构造一个1-10*n的均 ...

  3. [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 functio ...

  4. 利用rand7()构造rand10()

    题意 已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10 参考代码 int rand7() { srand((int)time(NULL)) ...

  5. Java实现 LeetCode 470 用 Rand7() 实现 Rand10()

    470. 用 Rand7() 实现 Rand10() 已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数. 不要使用系 ...

  6. Eclipse用法和技巧三:自动生成Main方法2

    上一篇文章里面介绍了新建文件时候自动添加main方法,这里接着介绍自动联想main方法.       步骤一:输入"main” 步骤二:保持光标在上图位置,按ALT + /,再回车 上一篇文 ...

  7. Eclipse用法和技巧二:自动生成Main方法1

    刚开始编写java小程序,基本都要用到main方法.后期开发大一点的程序,也可以用main方法进行单元测试.总是编写main方法,感觉太无聊了,幸好Eclipse可以帮我们自动生成main方法.见图: ...

  8. 微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

    1.点评 对于IM系统来说,如何做到IM聊天消息离线差异拉取(差异拉取是为了节省流量).消息多端同步.消息顺序保证等,是典型的IM技术难点. 就像即时通讯网整理的以下IM开发干货系列一样: <I ...

  9. 深入V8引擎-Time核心方法之win篇(2)

    这一篇讲windows系统下TimeTicks的实现. 对于tick,V8写了相当长的一段discussion来讨论windows系统上计数的三种实现方法以及各自的优劣,注释在time.cc的572行 ...

随机推荐

  1. Hive安装步骤

    首先解压压缩包 然后进入bin 执行 ./hive 不过现在hive使用的是自己默认的数据库,不方便,可以通过配置使用MySQL数据库 创建hive-site.xml 粘贴一下内容 <confi ...

  2. 微信小程序的那些坑

    早闻微信小程序是个坑,结果名不虚传,细数一下我开发小程序遇过到坑. 1.UI组件过度封装. 微信小程序的组件是模仿react.js或vue.js的web组件设计的,并且封装了weui.css样式. P ...

  3. Mysql - 安装及初始化设置

    1. 下载mysql-5.7.13-tar.gz http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.13-linux-glibc2.5-x8 ...

  4. 【LeetCode】Binary Tree Preorder Traversal(二叉树的前序遍历)

    这道题是LeetCode里的第144道题. 题目要求: 给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很 ...

  5. 紫书第三章训练1 E - DNA Consensus String

    DNA (Deoxyribonucleic Acid) is the molecule which contains the genetic instructions. It consists of ...

  6. Python Mysql学习总结

    任何应用都离不开数据,所以在学习python的时候,当然也要学习一个如何用python操作数据库了.MySQLdb就是python对mysql数据库操作的模块.官方Introduction : MyS ...

  7. hihoCoder #1117 战争年代

    题目大意 对一棵树的节点染色.初始时每个点都染成颜色 $0$,然后进行 $m$ 轮操作.第 $i$ 轮操作:从 $[0,d_i]$ 中随机选出一个整数 $d$,将距离点 $x_i$ 不超过 $d$ 的 ...

  8. [luoguP1110] [ZJOI2007]报表统计(set暴力)

    传送门 两个multiset 一个记录相邻元素的差,一个放所有的元素 2个数组 val[i]记录第i个的值,last[i]记录第i个最后插入的数的值 然后乱搞 #include <set> ...

  9. C#.net制作验证码(英文与数字组成的4位随机数),以及MD5值的使用

    原文发布时间为:2008-09-22 -- 来源于本人的百度文章 [由搬家工具导入] 参考资料:http://www.cnblogs.com/gwazy/articles/139510.html 三个 ...

  10. luogu 1355 神秘大三角 判断点和三角形的位置关系 面积法 叉积法

    题目链接 题目描述 判断一个点与已知三角形的位置关系. 输入输出格式 输入格式: 前三行:每行一个坐标,表示该三角形的三个顶点 第四行:一个点的坐标,试判断该点与前三个点围成三角形的位置关系 (详见样 ...