0-1等概率发生器

258 阅读1分钟

等概率-->等概率

题目:给定一个函数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的概率是Pf()==1的概率是1-P。
 那么连续执行2f()的结果如下
   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这样就能构造出等概率返回01g()函数了
   

伪代码如下:

 ​
 public static int g(){
   int ans =0;
   do{
     ans = f();
     //2次返回相同则重新再取一次
   }while(ans==f());
   return ans;
 }
 ​