一个抽奖算法

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}

可见次数越多, 中奖概率越平稳



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值