一个抽奖算法
2014-01-10 17:49
232 查看
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TreeMap; import java.util.Map.Entry; /** * * * 中奖算法: 如A、B、C、D等奖的中奖概率是0.1、0.2、0.3、0.4, S=0.1+0.2+0.3+0.4 然后每次抽奖的时候产生一个0到1之间的随机数r, 用r*S得出值v,如果0 < v <= 0.1,那么就是抽中了A, 如果0.1 < v <= 0.1 + 0.2,则抽中了B, 如果0.1 + 0.2< v <= 0.1 + 0.2 + 0.3,则抽中了C, 如果0.1 + 0.2 + 0.3 < v <= 0.1 + 0.2 + 0.3 + 0.4,则抽中了D 。 如果某次中了A奖品,但该奖品已被抽完, 则重新获取随机数,直到获得未被抽完的奖品; */ public class T { //等级、等级最大值、等级最小值 static class Section { String level; double min; double max; public Section(String level, double min, double max) { super(); this.level = level; this.min = min; this.max = max; } public String getLevel() { return level; } public void setLevel(String level) { this.level = level; } public double getMin() { return min; } public void setMin(double min) { this.min = min; } public double getMax() { return max; } public void setMax(double max) { this.max = max; } public String toString() { return "{level:" + level + ",min:" + min + ",max:" + max + "}"; } } //随机数 static Random r = new Random(); //每组抽奖次数 static int count = 1000; public static void main(String[] args) { List<Section> p = new ArrayList<Section>(); // 等级关系 p.add(new Section("A", 0, 0.1)); p.add(new Section("B", 0.1, 0.1 + 0.2)); p.add(new Section("C", 0.1 + 0.2, 0.1 + 0.2 + 0.3)); p.add(new Section("D", 0.1 + 0.2 + 0.3, 0.1 + 0.2 + 0.3 + 0.4)); // 统计中奖次数用 Map<String, Integer> m = new TreeMap<String, Integer>(); for (int i = 0; i < 4; i++) { m.put(p.get(i).getLevel(), 0); } // 统计概率用 Map<String, Double> m2 = new TreeMap<String, Double>(); for (int n = 0; n < 10; n++) { for (int i = 0; i < count; i++) { // 一次抽奖 win(p, m); } // 统计概率 Set<Map.Entry<String, Integer>> set = m.entrySet(); for (Iterator<Map.Entry<String, Integer>> it = set.iterator(); it.hasNext();) { Entry<String, Integer> e = it.next(); m2.put(e.getKey(), (e.getValue() + 0.0) / count); } System.out.print("等级次数:" + m); System.out.println(" 等级概率" + m2); // 清空中奖次数用map中的value for (int i = 0; i < 4; i++) { m.put(p.get(i).getLevel(), 0); } } } //一次抽奖 private static void win(List<Section> p, Map<String, Integer> m) { // 随机数中奖 double d = r.nextDouble(); // System.out.println(d); for (int j = 0; j < p.size(); j++) { Section s = p.get(j); if (d > s.getMin() && d <= s.getMax()) { m.put(s.getLevel(), m.get(s.getLevel()) + 1); break; } } } }
第一次测试, 每组抽奖100次,共10组,中奖数和中奖概率如下:
等级次数:{A=5, B=16, C=37, D=42} 等级概率{A=0.05, B=0.16, C=0.37, D=0.42}
等级次数:{A=10, B=21, C=29, D=40} 等级概率{A=0.1, B=0.21, C=0.29, D=0.4}
等级次数:{A=11, B=23, C=30, D=36} 等级概率{A=0.11, B=0.23, C=0.3, D=0.36}
等级次数:{A=11, B=25, C=25, D=39} 等级概率{A=0.11, B=0.25, C=0.25, D=0.39}
等级次数:{A=13, B=18, C=30, D=39} 等级概率{A=0.13, B=0.18, C=0.3, D=0.39}
等级次数:{A=13, B=24, C=21, D=42} 等级概率{A=0.13, B=0.24, C=0.21, D=0.42}
等级次数:{A=7, B=27, C=24, D=42} 等级概率{A=0.07, B=0.27, C=0.24, D=0.42}
等级次数:{A=8, B=14, C=32, D=46} 等级概率{A=0.08, B=0.14, C=0.32, D=0.46}
等级次数:{A=13, B=22, C=28, D=37} 等级概率{A=0.13, B=0.22, C=0.28, D=0.37}
等级次数:{A=8, B=31, C=25, D=36} 等级概率{A=0.08, B=0.31, C=0.25, D=0.36}
第2次测试, 每组抽奖1000次,共10组,中奖数和中奖概率如下:
等级次数:{A=106, B=188, C=317, D=389} 等级概率{A=0.106, B=0.188, C=0.317, D=0.389}
等级次数:{A=105, B=184, C=295, D=416} 等级概率{A=0.105, B=0.184, C=0.295, D=0.416}
等级次数:{A=84, B=219, C=292, D=405} 等级概率{A=0.084, B=0.219, C=0.292, D=0.405}
等级次数:{A=101, B=206, C=284, D=409} 等级概率{A=0.101, B=0.206, C=0.284, D=0.409}
等级次数:{A=99, B=201, C=279, D=421} 等级概率{A=0.099, B=0.201, C=0.279, D=0.421}
等级次数:{A=81, B=193, C=311, D=415} 等级概率{A=0.081, B=0.193, C=0.311, D=0.415}
等级次数:{A=108, B=202, C=310, D=380} 等级概率{A=0.108, B=0.202, C=0.31, D=0.38}
等级次数:{A=98, B=203, C=303, D=396} 等级概率{A=0.098, B=0.203, C=0.303, D=0.396}
等级次数:{A=101, B=190, C=307, D=402} 等级概率{A=0.101, B=0.19, C=0.307, D=0.402}
等级次数:{A=101, B=195, C=343, D=361} 等级概率{A=0.101, B=0.195, C=0.343, D=0.361}
第3次测试, 每组抽奖10000次,共10组,中奖数和中奖概率如下:
等级次数:{A=1029, B=1947, C=2965, D=4059} 等级概率{A=0.1029, B=0.1947, C=0.2965, D=0.4059}
等级次数:{A=1018, B=2014, C=2955, D=4013} 等级概率{A=0.1018, B=0.2014, C=0.2955, D=0.4013}
等级次数:{A=1048, B=1940, C=2981, D=4031} 等级概率{A=0.1048, B=0.194, C=0.2981, D=0.4031}
等级次数:{A=1024, B=1989, C=2966, D=4021} 等级概率{A=0.1024, B=0.1989, C=0.2966, D=0.4021}
等级次数:{A=1041, B=2006, C=2879, D=4074} 等级概率{A=0.1041, B=0.2006, C=0.2879, D=0.4074}
等级次数:{A=961, B=2053, C=2983, D=4003} 等级概率{A=0.0961, B=0.2053, C=0.2983, D=0.4003}
等级次数:{A=1039, B=1985, C=2953, D=4023} 等级概率{A=0.1039, B=0.1985, C=0.2953, D=0.4023}
等级次数:{A=1034, B=2008, C=2925, D=4033} 等级概率{A=0.1034, B=0.2008, C=0.2925, D=0.4033}
等级次数:{A=1024, B=1996, C=3044, D=3936} 等级概率{A=0.1024, B=0.1996, C=0.3044, D=0.3936}
等级次数:{A=995, B=2051, C=2933, D=4021} 等级概率{A=0.0995, B=0.2051, C=0.2933, D=0.4021}
第3次测试, 每组抽奖100000次,共10组,中奖数和中奖概率如下:
等级次数:{A=10117, B=20029, C=29723, D=40131} 等级概率{A=0.10117, B=0.20029, C=0.29723, D=0.40131}
等级次数:{A=9835, B=20004, C=29858, D=40303} 等级概率{A=0.09835, B=0.20004, C=0.29858, D=0.40303}
等级次数:{A=10078, B=19981, C=30044, D=39897} 等级概率{A=0.10078, B=0.19981, C=0.30044, D=0.39897}
等级次数:{A=10100, B=19977, C=29994, D=39929} 等级概率{A=0.101, B=0.19977, C=0.29994, D=0.39929}
等级次数:{A=10153, B=19891, C=29980, D=39976} 等级概率{A=0.10153, B=0.19891, C=0.2998, D=0.39976}
等级次数:{A=10039, B=19767, C=30050, D=40144} 等级概率{A=0.10039, B=0.19767, C=0.3005, D=0.40144}
等级次数:{A=9840, B=19938, C=30037, D=40185} 等级概率{A=0.0984, B=0.19938, C=0.30037, D=0.40185}
等级次数:{A=10058, B=19887, C=30252, D=39803} 等级概率{A=0.10058, B=0.19887, C=0.30252, D=0.39803}
等级次数:{A=10113, B=20162, C=30076, D=39649} 等级概率{A=0.10113, B=0.20162, C=0.30076, D=0.39649}
等级次数:{A=10007, B=20207, C=29661, D=40125} 等级概率{A=0.10007, B=0.20207, C=0.29661, D=0.40125}
可见次数越多, 中奖概率越平稳
相关文章推荐
- 有关抽奖的一个算法
- 如何实现一个抽奖的算法
- 一个经典概率算法(用于抽奖等场景)
- 一个简单的抽奖算法
- 一个简单抽奖算法的实现以及如何预防超中
- 分享一个PHP抽奖算法程序代码
- 牛客网 小东所在公司要发年终奖,而小东恰好获得了最高福利,他要在公司年会上参与一个抽奖游游戏在一个6*6的棋盘上进行,上面放着36个价值不等的礼物,每个小的棋盘上面放置着一个礼物,他需要从左上角开始游戏,每次只能向下或者向右移动一步,到达右下角停止,一路上的格子里的礼物小东都能拿到,请设计一个算法使小东拿到价值最高的礼物
- 一个信息可视化Demo的设计(三):算法设计
- POJ 3061 Subsequence 尺取法,一个屌屌的O(n)算法
- 一个奇妙、离奇的算法题
- 算法是代码的灵魂-判断一个字符串是否是回文字符串
- 一个非常简单的算法题是否愿意挑战一下呢
- 算法一:循环遍历一个数组
- 抽奖算法
- 一个智能运维算法测试方法
- 一个字符旋转的算法
- 今天完成了一个加密解密算法的编写
- 我自己写了一个判断两条多段线重叠的算法。希望大家给点意见或建议。
- 已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数
- 程序员面试金典——解题总结: 9.18高难度题 18.6设计一个算法,给定10亿数字,找出最小的100万个数字。假定计算机内存足以容纳全部10亿个数字。