等概率-->等概率
题目:给定一个函数f1(),f1()可以等几率的返回1~5。现在只能使用f1()来构造出等概率返回1到7的函数。
首先通过f1(),构造出等概率返回0和1的函数f2
// 等概率返回1~5
private static int f1() {
return (int) (Math.random() * 5) + 1;
}
// 使用f1(),等概率随机返回0和1
private static int f2() {
int ans = 0;
do {
ans = f1();
} while (ans == 4);
return ans < 3 ? 0 : 1;
}
1~7就是0到6 +1 。使用3位2进制即可表示 。
000 --> 0
001 --> 1
010 --> 2
011 --> 3
100 --> 4
101 --> 5
110 --> 6
111 --> 7
使用f2()得到二进制000到111 ,既可以等概率返回十进制0~7
private static int f3() {
return (f2() << 2) + (f2() << 1) + (f2());
}
将f3()转换成等概率返回1~7
private static int f4() {
int ans = 0;
do {
ans = f3();
} while (ans == 7);
return ans+1;
}
测试:
public static void main(String[] args) {
int testTimes = 100000;
int count = 0;
for (int i = 0; i < testTimes; i++) {
if (f2() == 0) {
count++;
}
}
System.out.println("f2()==0 的概率 " + (double) count / (double) testTimes);
System.out.println("------------------------");
int[] counts = new int[7];
for (int i = 0; i < testTimes; i++) {
int num = f4();
counts[num-1]++;
}
for (int i = 1; i <= counts.length; i++) {
System.out.println(i + "这个数,出现了 " + counts[i-1] + " 次");
}
}
输出:
f2()==0 的概率 0.50036
------------------------
1这个数,出现了 14308 次
2这个数,出现了 13921 次
3这个数,出现了 14485 次
4这个数,出现了 14289 次
5这个数,出现了 14061 次
6这个数,出现了 14523 次
7这个数,出现了 14413 次
不等概率-->等概率
题目:给你一个函数f(),f()返回0的概率是P,返回1的概率是1-P。仅使用f()构造出能够等概率返回0和1的g()函数。
分析:
f()==0的概率是P,f()==1的概率是1-P。
那么连续执行2次f()的结果如下
0 0的概率是p*p
1 1的概率是(1-p)*(1-p)
0 1的概率是p*(1-p)
1 0的概率是(1-p)*p
后两者的概率是等价的。我们可以使用 0 1代表1 , 1 0代表1这样就能构造出等概率返回0和1的g()函数了
伪代码如下:
public static int g(){
int ans =0;
do{
ans = f();
//2次返回相同则重新再取一次
}while(ans==f());
return ans;
}