文章目录
1. Math.random()
Math.random方法:等概率
生成 [ 0, 1)的随机小数,返回double类型
2. 修改随机生成数的概率
2.1 使用等概率Math.random() 变 不等概率g()
- 原理以及语法:
- 案例:
上述代码如下:
public class Main {
public static void main(String[] args) throws Exception {
int testCount = 10000000;
int count = 0;
double x = 0.3;
for (int i = 0; i < testCount; i++) {
count = Math.max(Math.random(), Math.random()) <= x ? ++count : count;
}
System.out.println("统计概率为:" + (double)count / testCount);
System.out.println(Math.pow(x, 2));
}
}
2.2 使用不等概率f() 变 等概率g()
代码:
public class Main {
public static void main(String[] args) throws Exception {
int testCount = 10000000;
int count = 0;
for (int i = 0; i < testCount; i++) {
count = zero_one_fair() == 0 ? ++count : count;
}
System.out.println("统计概率为:" + (double)count / testCount);
}
// 不等概率的 0-1生成器:假设生成0的概率为0.84,生成1的概率为0.16
public static int zero_one_unfair() {
return Math.random() <= 0.84 ? 0 : 1;
}
// 使用不等概率的 0-1生成器 生成 等概率的0-1生成器
public static int zero_one_fair() {
int ans1 = -1, ans2 = -1;
do {
ans1 = zero_one_unfair();
ans2 = zero_one_unfair();
} while ((ans1 == 0 && ans2 == 0) || (ans1 == 1 && ans2 == 1));
return ans1;
}
}
输出:
3. 使用Math.random() 随机生成[a, b]的小数
4. 使用Math.random() 随机生成[a, b]的整数
4.1 一个案例引发的思路
4.2 代码
public class Main {
public static void main(String[] args) throws Exception {
int testCount = 10000000;
int count = 0;
for (int i = 0; i < testCount; i++) {
count = randomIntNum(1, 10) <= 5 ? ++count : count;
}
System.out.println("统计概率为:" + (double)count / testCount);
}
// 构造等概率 0-1生成器
public static int zero_one() {
return (int) (Math.random() * 2);
}
// 等待率生成:[a, b]的整数
public static int randomIntNum(int a, int b) {
int numCount = b - a + 1; // 需要生成整数的个数
/*
1. 如果只需要等概率生成两个数,则直接使用0-1随机生成器。
*/
if (2 == numCount)
return a + zero_one();
/*
2. 生成的数个数大于两个,则使用 多个0-1随机生成器 等概率生成多个数
*/
int binaryDigits = getBinaryDigits(numCount);// 得到需要几个二进制位
// 使用binaryDigits个等概率0-1生成器,得到等概率生成[a, b]的整数
int ans = 0; // 结果
do {
ans = 0;
for (int i = binaryDigits-1; i >= 0 ; i--) {
ans += (zero_one() << i);
}
} while ((b-a) < ans && ans < Math.pow(2, binaryDigits));
return a + ans;
}
// 得到一个数的二进制位数
public static int getBinaryDigits(int num) {
int digits = 0; // 存放需要几位二进制数
int maxBinaryValue = 1;
for (int i = 0; i < 32; i++) {
if (num <= maxBinaryValue) {
digits = i;
break;
}
maxBinaryValue *= 2;
}
return digits;
}
}
输出: