一个简单的概率算法
2013-11-08 10:14
357 查看
概率算法:假设我们有5个大小不等的面积(对应5个不同的奖项),共同组成一个圆,总面积为1(必须),那么随机一个double数字出来,它究竟落入哪一个小面,该面的id就是对应的奖项。
算法的意思是:多个概率的大小总和等于1,相当于一个半径为1的圆。当我们随机一个double数出来之后,将它与概率相比,如果第1个概率小于随机数,则第1个概率加上第二个概率与随机数相比,以此类推下去,必然有一个概率被加上之后能大于这个随机数,因为随机数的范围[0,1),而我们的圆的总面积是1.此时我们就能得到最后被加上的概率的位置,返回它的位置就是我们需要的结果。
下面测试一下:
运行结果:9:21:24:9:37
这个结果符合我们设定的比例:1:2:2:1:4,就是说,概率算法是正确的。
有的人可能会问,用面积来计算概率的话,如果概率的顺序调整一下,比如4:2:2:1:1,方法getRandomId()中count先后出现的结果就不一样,那与随机数比较的结果是不是就不一样了。
这里就要考虑到一个问题,那就是随机数,大家都知道随机数是没有规律出现的,也就是说在一定次数里面,每一个数字都有可能出现,换句话说就是分布平均的。
那么如果概率变换顺序,对于随机数来说还是平均分布,将随机数当成一个个点来看待,如果一个概率够大,那么落在其中的点就会更多,相反如果概率较小的则落点就少。那么概率分布就跟顺序没有关系了。
/** * 利用随机数,配合设定的概率,取得获得的奖项等次,【符合概率分布】 * @param list 数据库里设定的概率 * @return 随机获得的奖项等次 */ public String getRandomId(List<Map<String, Object>> list){ try { double randomNumber; randomNumber = Math.random(); //随机数 double count=0; //概率和 int i = 0; //当randomNumber>[概率1],则比较randomNumber是不是大于[概率1]+[概率2],以此类推 //直到randomNumber<[概率1]+[概率2]+..+[概率i],返回i。 for(i=0;i<list.size();i++){ count+=Double.parseDouble(list.get(i).get("prob").toString()); if(randomNumber<count){ break; } } return (i+1)+""; } catch (NumberFormatException e) { e.printStackTrace(); return "100"; } }
算法的意思是:多个概率的大小总和等于1,相当于一个半径为1的圆。当我们随机一个double数出来之后,将它与概率相比,如果第1个概率小于随机数,则第1个概率加上第二个概率与随机数相比,以此类推下去,必然有一个概率被加上之后能大于这个随机数,因为随机数的范围[0,1),而我们的圆的总面积是1.此时我们就能得到最后被加上的概率的位置,返回它的位置就是我们需要的结果。
下面测试一下:
public static void main(String[] args) { //我从数据库查出的概率集合,有4个奖项,第5个是为了凑合1的总和,也可以是不中奖的1个概率。 //分别是:0.1; 0.2; 0.2; 0.1; 0.4 List<Map<String, Object>> list=(new LotteryService()).getProbability(); LotteryUtil lt=new LotteryUtil(); //6个计数,包含getRandomId()报错的情况。 int count1=0; int count2=0; int count3=0; int count4=0; int count5=0; int countError=0; for(int i=0;i<100;i++){ int n=Integer.parseInt(lt.getRandomId(list)); //当得到的奖项ID=1,则count1++,下同。 if(n==1){ count1++; } else if(n==2){ count2++; } else if(n==3){ count3++; } else if(n==4){ count4++; } else if(n==5){ count5++; }else{ countError++; } System.out.print(n+"\t"); } System.out.println(); //输出概率分布情况 System.out.println(count1+":"+count2+":"+count3+":"+count4+":"+count5); }
运行结果:9:21:24:9:37
这个结果符合我们设定的比例:1:2:2:1:4,就是说,概率算法是正确的。
有的人可能会问,用面积来计算概率的话,如果概率的顺序调整一下,比如4:2:2:1:1,方法getRandomId()中count先后出现的结果就不一样,那与随机数比较的结果是不是就不一样了。
这里就要考虑到一个问题,那就是随机数,大家都知道随机数是没有规律出现的,也就是说在一定次数里面,每一个数字都有可能出现,换句话说就是分布平均的。
那么如果概率变换顺序,对于随机数来说还是平均分布,将随机数当成一个个点来看待,如果一个概率够大,那么落在其中的点就会更多,相反如果概率较小的则落点就少。那么概率分布就跟顺序没有关系了。
相关文章推荐
- 一个简单的镜头稳定算法
- 一个简单的子集产生算法
- 一个简单的子集产生算法
- 火车运煤问题 - 增加一个简单算法实现
- 一个非常简单的求随机数的算法
- 由一个简单算法想到的程序员素养问题
- 一天一个算法题-简单的-递归-计算球的落下
- 一个简单的大数乘法算法
- 一个简单的抽奖算法
- 算法题目------【一个桶内100个白球,100个黑球,最后一个是黑球的概率是多少?】
- CU上看到的一个简单的算法帖子
- 一个非常简单的算法题是否愿意挑战一下呢
- 一个简单的算法---实现找出数组中一个数字出现次数最多的数字
- 一个简单的算法2
- 采用KNN算法实现一个简单的推荐系统
- 一个将阿拉伯数字转换成中文大写的最简单算法
- 一个简单的实现找出数组中一个数字出现次数最多的数字的算法
- c#打包文件解压缩 C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法 一个简单例子理解C#的协变和逆变 对于过长字符串的大小比对
- SVM基础一:一个简单的训练算法
- 一个简单的算法题目,搞了半天,希望大家能给点意见