1等概率的生成(0-8)范围内的正整数
// Math.random 数据范围[0,1) 且 是 等概率的产生随机数
// 应用:
// 1.生成等概率的整数(等概率的生成[0-8]范围内的正整数
int value = (int) (Math.random() * 9);
System.out.println("value = " + value);
2 从a~b等概率事件,算c~d的等概率事件
已知函数f(x)在3-19上等概率,算出一个g(x)在20-56上等概率?
思路:条件函数f 向目标函数转换,具体如下:
1.56-20=36, 20-56的等概率 等价于 0-36的等概率+20,所以就去找0-36的等概率事件就行。
2把已知的等概率函数转f(x) 化为 0,1事件发生器,即:归一化
19-3+1=17, 3-19共17个数,从中间一分(3+19=22,22/2=11 中间一个数是11) 3-10 ,11, 12-19 。3-10 转化为0事件,12-19转换为1事件,遇到11,重试,因为3-19是等概率的。所以 0,1 发生器也是等概率的。
如果是偶数次,就没有中间11 重试的事了。
/**
* 条件函数fx
* @return
*/
private static int fx() {
// 3-19等概率事件 转换为 [0-16] +3的等概率事件
int randomInt = (int) (Math.random() * 17 + 3);
System.out.println("randomInt = " + randomInt);
return randomInt;
}
}
/**
* fx转换为 0,1 转换器
*/
private static int f2() {
int fxValue = 0;
do {
fxValue = fx();
} while (fxValue == 11);
return fxValue < 11 ? 0 : 1;
}
3.重点来了,如何把已知的等概率的 0,1发生器,转换为0-36的等概率事件。方法就是通过二进制位的左移来实现。0-36的数,看着有 37个,但是最大的数也就占6位。从最高位6位,开始处理,到第5位,。。。,到第1位。每一位都是等概率的。所以整体0-36的数,产生的概率都是等概率的。
/**
* 生成0 -36 的每一个数
* 已知最小数 00000=0
* 最大数:100100
* 五位中最大数:111111=63 大于 36,所以大于20的要重新算
*
* @return
*/
private static int f3() {
int value = (f2() << 5) + (f2() << 4) + (f2() << 2) + (f2() << 2) + (f2() << 1);
return value;
}
/**
* 包装一层,大于36的重新计算
*
* @return
*/
public static int f4() {
int value = 0;
do {
value = f3();
} while (value > 36);
return value + 20;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println("f4() = " + f4());
}
f4();
}