给定一个等概率随机产生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. 06 python下

    # st='hello kitty {name} is {age}' # # print(st.count('l')) # 统计元素个数 # print(st.capitalize()) # 首字母大 ...

  2. 30_react_router基本使用

    项目结构: import React from 'react' import {render} from 'react-dom' import {BrowserRouter} from 'react- ...

  3. Signals的使用(通知)

    https://docs.djangoproject.com/en/2.1/topics/signals/

  4. RAD Studio 10.3 来了

    官方原版下载链接:HTTP FTP 官方更新说明:http://docwiki.embarcadero.com/RADStudio/Rio/en/What's_New [官方更新说明简译]1.Delp ...

  5. STL里的内存池实现

    这个貌似有点复杂,解决的主要问题 就是 减少 内存分配次数,减少用户态核心态切换中断次数,提高运行速度,预分配 和线程池一个道理,预分配 ////////////////////自由链表 union ...

  6. 25.Hibernate-配置文件.md

    目录 1.主配置文件 1.1定义 1.1.1分类 1.1.2分类 1.1.3不使用配置文件生成表 1.2教程 2. 映射配置文件 1.主配置文件 1.1定义 1.1.1分类 在hibernate的配置 ...

  7. ajax请求导致status为canceled(无任何回调数据)的原因

    1.故障现象 一个普通的ajax请求,请求能够到达controller,也能正常处理业务,但是ajax的回调函数为空,即没有任何状态和数据返回,使用谷歌浏览器查看请求状态如下图: 出现该错误:简单来说 ...

  8. 针对piix4_smbus ****host smbus controller not enabled的解决方法

    SMBus 目录 SMBus与I2C的差别 SMBus 是 System Management Bus 的缩写,是1995年由Intel提出的,应用于移动PC和桌面PC系统中的低速率通讯.它主要是希望 ...

  9. DRF中的序列化器

    DRF中的序列化器详细应用   视图的功能:说白了就是接收前端请求,进行数据处理 (这里的处理包括:如果前端是GET请求,则构造查询集,将结果返回,这个过程为序列化:如果前端是POST请求,假如要对数 ...

  10. HDU-1078.FatMouseandCheese(线性dp + dfs)

    本题大意:在一个n * n的迷宫内进行移动,左上角为初始位置,每次可以走的步数不能超过m,并且每次走的方格上面的数字要大于前一次走的放个数字,不能走到格子外面,问如何能使得到的数字和最大. 本题思路: ...