给定一个等概率随机产生1~M的随机函数rand1ToM如下:

public int rand1ToM(int m) {
return (int) (Math.random() * m) + 1;
}

除此之外不能使用任何额外的随机机制。有两个输入参数分别为m和n,请用rand1ToM(m)实现等概率随机产生1~n的随机函数rand1ToN。

Solution

在做这道题之前,我们先来看一个例子,由rand1to5如何产生rand1to7?稍加思考,不难发现可以有以下做法:

rand1to5(5) 等概率产生: 1 2 3 4 5

rand1to5(5) – 1 等概率产生: 0 1 2 3 4

(rand1to5(5) – 1) * 5 等概率产生: 0 5 10 15 20

(rand1to5(5) – 1) * 5 + (rand1to5(5) – 1) 等概论产生: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

现在 (rand1to5(5) – 1) * 5 + (rand1to5(5) – 1) 的范围已经超过1-7了,因此不用继续再扩大随机数函数可以生成的范围。

现在的问题是,已有的0-24这5个数中,0-20通过模7可以生成3套0-6,也就是说0-20可以等概率生成0-6,通过加1即可等概率生成1-7。但是,由于21-24的存在,0-24生成0-3的概率会大于4-6(加1后生成1-4的概率会大于5-7),如何解决?如果随机数生成函数生成21-24范围的数,那么直接忽略这次随机数的生成。代码如下:

public int rand1To5() {
return (int) (Math.random() * 5) + 1;
}
public int rand1To7() {
int num = 0;
do {
num = (rand1To5() - 1) * 5 + rand1To5() - 1;
} while (num > 20);
return num % 7 + 1;
}

现在来看,如何解决rand1tom生成rand1ton。其实一句话就可以总结,即以m倍的规模不断扩大随机数范围直到超过1ton的范围,之后使用do while循环筛选掉多余的使得概论不均等的数即可。

进阶

如果预先给定的随机数生成器以p的概论生成0,(1-p)的概率生成1,那么怎么通过该随机数生成器等概率生成的1-n?

无论概率p怎么变化,连续两次生成0 1或者1 0的概率都是p(1-p),因此我们只要排除掉0 0和1 1的情况就可以等概率生成0 1,如下:

public int rand01p() {
// you can change p as you like
double p = 0.83;
return Math.random() < p ? 0 : 1;
} public int rand01() {
int num;
do {
num = rand01p();
} while (num == rand01p());
return num == 1 ? 1 : 0;
}

而通过0 1 来生成 1-n的方法和之前的是一样的。

 

rand_1tom 产生 rand_1ton的更多相关文章

随机推荐

  1. 李清华201772020113《面向对象程序设计(java)》第二周学习总结

    李清华201772020113<面向对象程序设计(java)>第二周学习总结 第一部分 理论知识 第三章 本章主要讲了java基本知识中的标识符,关键字,注释,以及数据类型,变量,运算符, ...

  2. Mysql 和 SQLServer 使用SQL差异比较

    查询前100条数据 #mysql ; #sqlserver * from table_name ; 从数据库.表 定位表 #mysql写法:库名.表名 select password from Inf ...

  3. Java执行shell遇到的各种问题

    1.判断子进程是否执行结束 有的时候我们用java调用shell之后,之后的操作要在Process子进程正常执行结束的情况下才可以继续,所以我们需要判断Process进程什么时候终止. Process ...

  4. codestyle 设置问题

    参考: https://blog.csdn.net/hugh77/article/details/43268195 使用 4 空格缩进,而非 TAB. 在小缩进(可以嵌套更深)和大缩进(更易读)之间, ...

  5. java中封装类(二)

    java中的数字类型包括 Byte,Short,Integer,Long,Float,Double.其中前四个是整数,后两个是浮点数. 在说java中数字类型之前先来看看它们统一的基类Number. ...

  6. 高性能迷你React框架anujs1.0.8发布

    本版本由于得到业务线同学的大力支持,掀出许多问题,因此改进地方良多,为anujs在完美替换React的道路上前进了不少.现在anujs经测试可以运行于IE7中.至少怎么做可以参看官网,https:// ...

  7. uname命令详解

    1.简介: uname命令用于打印当前系统相关信息(内核版本号.硬件架构.主机名称和操作系统类型等). 2.命令语法: uname (选项) 3.选项: -a或--all:显示全部的信息: -m或-- ...

  8. Javascript面试题收集

    第一部分“ 来源: http://bbs.miaov.com/forum.php?mod=viewthread&tid=6974 1.var a = b = 1; ——这样定义变量的隐患 fu ...

  9. [Ting's笔记Day3]解决Git常见错误non-fast-forward问题

    写文章最难的部分,是找题材! 所以最近每次遇到bug或错误都挺兴奋开心(zflwx)的,因为又可以写笔记了 也可以记录新手学习之路上遇到的常见问题,提供其他新手参考. 最近学Udemy平台Ruby学习 ...

  10. Xshell 6安装与使用教程

    随着xshell5出现评估期已过的问题,发现好多人不知道怎么下载免费版的Xshell,在这里我将详细告诉大家如何下载和安装最新的Xshell6远程管理工具. Xshell安装 1.进入xshell英文 ...