已知一个函数rand7()能够生成1-7的随机数,请给出一个函数rand10(),该函数能够生成1-10的随机数。
来源:互联网 发布:如何设置淘宝客优惠券 编辑:程序博客网 时间:2024/04/30 15:44
已知一个函数rand7()能够生成1-7的随机数,请给出一个函数rand10(),该函数能够生成1-10的随机数。
Posted on 2013-05-20 22:55 鑫龙 阅读(445) 评论(0) 编辑 收藏 引用 所属分类: 数据结构与算法题目:
已知一个函数rand7()能够生成1-7的随机数,请给出一个函数,该函数能够生成1-10的随机数。
思路:
假如已知一个函数能够生成1-49的随机数,那么如何以此生成1-10的随机数呢?
解法:
该解法基于一种叫做拒绝采样的方法。主要思想是只要产生一个目标范围内的随机数,则直接返回。如果产生的随机数不在目标范围内,则丢弃该值,重新取样。由于目标范围内的数字被选中的概率相等,这样一个均匀的分布生成了。
显然rand7至少需要执行2次,否则产生不了1-10的数字。通过运行rand7两次,可以生成1-49的整数,
1 2 3 4 5 6 7 1 1 2 3 4 5 6 7 2 8 9 10 1 2 3 4 3 5 6 7 8 9 10 1 4 2 3 4 5 6 7 8 5 9 10 1 2 3 4 5 6 6 7 8 9 10 * * 7 * * * * * * *由于49不是10的倍数,所以我们需要丢弃一些值,我们想要的数字范围为1-40,不在此范围则丢弃并重新取样。
代码:
[cpp] view plaincopy
- int rand10Imp() {
- int a, b, idx;
- while (true) {
- a = rand7();
- b = rand7();
- idx = b + (a-1)*7;
- if (idx <= 40)
- return 1 + (idx-1)%10;
- a = idx-40;
- b = rand7();
- // get uniform dist from 1 - 63
- idx = b + (a-1)*7;
- if (idx <= 60)
- return 1 + (idx-1)%10;
- a = idx-60;
- b = rand7();
- // get uniform dist from 1-21
- idx = b + (a-1)*7;
- if (idx <= 20)
- return 1 + (idx-1)%10;
- }
- }
E(# calls to rand7) = 2 * (40/49) + 3 * (9/49) * (60/63) + 4 * (9/49) * (3/63) * (20/21) + (9/49) * (3/63) * (1/21) * [ 6 * (40/49) + 7 * (9/49) * (60/63) + 8 * (9/49) * (3/63) * (20/21) ] + ((9/49) * (3/63) * (1/21))2 * [ 10 * (40/49) + 11 * (9/49) * (60/63) + 12 * (9/49) * (3/63) * (20/21) ] + ... = 2.2123这里期望次数为2.21,比起未优化的2.45次减少了大概10%。
本帖最后由 jerryz920 于 2010-07-08 20:34 编辑
这个其实和算法导论上的一个题很像么:已知random等概率返回0或者1,那么试写一个函数等概率返回[a,b]之间的整数。思路就是2进制表示[0, b-a]之间的数,先计算出至少需要多少位,按位生成一个二进制数,一旦大于b-a就重新生成。放到这里的话,表示成5进制就可以了~
推广一下:对于等概率可以生成k个连续整数函数的函数randomk,设计生成[a,b]之间的整数的算法:
令n = b - a;则等概率生成[0,n]上的一个整数即可。于是用k进制表示生成的整数,设m=ceiling(logk(n)), 期望的运行时间为t*m* i * (1 - (n+1)/k^m)^(i-1) * ((n+1)/k^m),i从1加到无穷,t表示randomk的运行时间,那么计算这个级数的值为t*m*k^m/(n+1).
带入到这个题目,期望运行时间为50*t/7,还是很快的。
这个其实和算法导论上的一个题很像么:已知random等概率返回0或者1,那么试写一个函数等概率返回[a,b]之间的整数。思路就是2进制表示[0, b-a]之间的数,先计算出至少需要多少位,按位生成一个二进制数,一旦大于b-a就重新生成。放到这里的话,表示成5进制就可以了~
推广一下:对于等概率可以生成k个连续整数函数的函数randomk,设计生成[a,b]之间的整数的算法:
令n = b - a;则等概率生成[0,n]上的一个整数即可。于是用k进制表示生成的整数,设m=ceiling(logk(n)), 期望的运行时间为t*m* i * (1 - (n+1)/k^m)^(i-1) * ((n+1)/k^m),i从1加到无穷,t表示randomk的运行时间,那么计算这个级数的值为t*m*k^m/(n+1).
带入到这个题目,期望运行时间为50*t/7,还是很快的。
0 0
- 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数rand10(),该函数能够生成1-10的随机数。
- 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数rand10(),该函数能够生成1-10的随机数。
- 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数rand10(),该函数能够生成1-10的随机数。
- 已知随机数函数rand7(),如何构造rand10()函数
- 一个随机数生成函数
- 一个随机数生成函数
- 由rand7生成rand10以及随机数生成方法的讨论
- 由rand7生成rand10以及随机数生成方法的讨论
- 由rand7生成rand10以及随机数生成方法的讨论
- 由rand7生成rand10以及随机数生成方法的讨论
- 已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10()
- 给定一个rand5的随机数,生成rand7的随机数
- 数据结构算法面试题精选及整理-随机数rand7生成rand10函数
- 给定一个能生成1到5随机数的函数,如何利用它来生成1到7的随机数。
- 给定一个自定义函数,random5() 可以随机生成1-5之间的随机数,请利用rondom5()定义一个rondom
- 已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10。
- 已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10
- 已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10
- C++11 新特性<一>
- python打印列表中的内容,而不是unicode字符
- 枚举类型
- Tomcat7新特性?cookie HttpOnly的那些事(sessionid获取麻烦了)
- 创建一个有序链表
- 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数rand10(),该函数能够生成1-10的随机数。
- 公务车订购国产化 多款车型入采购名单
- POJ 1948 Triangular Pastures (用所有的线段组成最大的三角形) DP || 携程员工运动会场地问题
- 十种常用排序算法浅析 附C++实现
- UINavigationController的横屏问题
- android JNI : ReferenceTable overflow
- 谈谈EJB是如何发布Web Service的
- 怎么引蜘蛛啊
- 平均背景提取2