您的位置:首页 > 其它

一个抽奖算法

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}

可见次数越多, 中奖概率越平稳
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐