不独立事件的条件概率选取——[即时]抽取【JAVA SE】

来源:互联网 发布:响应式网站整站源码 编辑:程序博客网 时间:2024/06/14 19:39

在写抽奖程序的时候碰到的一个问题:

1.在不预知组内成员的情况下(也不将数个中奖位置预读在内存中)保证每m个元素中总能抽中n个;

2.保证同等价值的元素抽取概率君相等为n‘/m;

3.n可分为n1,n2……;

 

选取的算法放弃经典概率的随机数生成,而改用条件概率;

1.首先判断第b/m位置的元素是否是a/n选取的特殊元素;P=(n-a)/(m-b+1);

2.进一步在a/n的基础上判断c/n’是否特殊;P=(n‘-c)/(n-a+1);

3.将2迭代在1的结果中判断;

4.若n'还可再分,重复2步骤;

 

实例代码如下

package full.hit;public class fullhit { public static int geted = 0; public static boolean task = false; public static int[] a = new int[21]; public static int[] b = new int[21]; public static int[] c = new int[21]; boolean first_hit(int round) {  boolean tempmark;  tempmark = false;  int rate = 0;  int fate = 0;  rate = (int) ((4 - geted) * 10000 / (20 - round + 1));  fate = (int) (10000 * Math.random() + 1);  if (fate <= rate) {   tempmark = true;   geted++;  }  return tempmark; } int socend_hit() {  int r;  int f;  int tempint = 0;  r = (int) 10000 / (4 - geted + 1);  f = (int) (10000 * Math.random());  if ((task == false) & (f <= r)) {   tempint = 1;   task = true;  } else {   tempint = 0;  }  return tempint; } public static void main(String[] args) {  int round = 0;  int s = 0;// 模拟楼层计数器  int ta = 0;// 一等奖检测  int tb = 0;// 二等奖检测  boolean mark;// 检测:不符合每20个出现1个一等奖和3个二等奖就终止程序  fullhit fh = new fullhit();  for (int i = 1; i <= 10000000; i++) {// 模拟10mX20个楼层   round = 0;   geted = 0;   task = false;   ta = 0;   tb = 0;   mark = true;   while (round < 20) {    round++;    if (fh.first_hit(round)) {     if (fh.socend_hit() == 1) {      // 模拟一等奖;      a[round]++;      ta++;     //省略处理一等奖的方法;     } else {      // 模拟二等奖;      b[round]++;      tb++;     //同上     }    } else {     // 模拟三等奖;     c[round]++;    同上    }   }   if (ta != 1) {    mark = false;   }   if (tb != 3) {    mark = false;   }   if (mark == false) {    System.out.println("error");    break;   }  }  for (int i = 1; i <= 20; i++) {   // 查看选中概率   System.out.print("a" + i + "的个数=" + a[i] + "(" + a[i] / 10000     + "%。)|");   System.out.print("b" + i + "的个数=" + b[i] + "(" + b[i] / 10000     + "%。)|");   System.out.print("c" + i + "的个数=" + c[i] + "(" + c[i] / 10000     + "%。)");   System.out.println("|");   s = a[i] + b[i] + c[i];  }  System.out.println(s); }}


 

 运行结果

a1的个数=499824(49%。)|b1的个数=1497290(149%。)|c1的个数=8002886(800%。)|
a2的个数=500605(50%。)|b2的个数=1498930(149%。)|c2的个数=8000465(800%。)|
a3的个数=500648(50%。)|b3的个数=1498506(149%。)|c3的个数=8000846(800%。)|
a4的个数=498906(49%。)|b4的个数=1499513(149%。)|c4的个数=8001581(800%。)|
a5的个数=499420(49%。)|b5的个数=1501569(150%。)|c5的个数=7999011(799%。)|
a6的个数=499057(49%。)|b6的个数=1499303(149%。)|c6的个数=8001640(800%。)|
a7的个数=499637(49%。)|b7的个数=1500461(150%。)|c7的个数=7999902(799%。)|
a8的个数=499751(49%。)|b8的个数=1497757(149%。)|c8的个数=8002492(800%。)|
a9的个数=499362(49%。)|b9的个数=1500223(150%。)|c9的个数=8000415(800%。)|
a10的个数=500398(50%。)|b10的个数=1501744(150%。)|c10的个数=7997858(799%。)|
a11的个数=500780(50%。)|b11的个数=1499652(149%。)|c11的个数=7999568(799%。)|
a12的个数=501419(50%。)|b12的个数=1500825(150%。)|c12的个数=7997756(799%。)|
a13的个数=499531(49%。)|b13的个数=1498670(149%。)|c13的个数=8001799(800%。)|
a14的个数=500125(50%。)|b14的个数=1499623(149%。)|c14的个数=8000252(800%。)|
a15的个数=499369(49%。)|b15的个数=1500529(150%。)|c15的个数=8000102(800%。)|
a16的个数=500528(50%。)|b16的个数=1499332(149%。)|c16的个数=8000140(800%。)|
a17的个数=500256(50%。)|b17的个数=1501182(150%。)|c17的个数=7998562(799%。)|
a18的个数=500026(50%。)|b18的个数=1500794(150%。)|c18的个数=7999180(799%。)|
a19的个数=500726(50%。)|b19的个数=1501076(150%。)|c19的个数=7998198(799%。)|
a20的个数=499632(49%。)|b20的个数=1503021(150%。)|c20的个数=7997347(799%。)|
10000000

可以看到a的概率在5%,b的概率在15%,c的概率在80%;同时mark没有因为每组中产生特殊元素不够而break;选取方式为单次产生随机,每次结果直接利用后消灭内存;符合开始的设定!

0 0
原创粉丝点击