Java抢红包代码实现及二倍均值法分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35393472/article/details/80073948

二倍均值法

剩余红包金额为M,剩余人数为N,那么有如下公式:

每次抢到的金额 = 随机区间 (0, M / N X 2)

这个公式,保证了每次随机金额的平均值是相等的,不会因为抢红包的先后顺序而造成不公平。

举个栗子:

假设有10个人,红包总额100元。

100/10X2 = 20, 所以第一个人的随机范围是(0,20 ),平均可以抢到10元。

假设第一个人随机到10元,那么剩余金额是100-10 = 90 元。

90/9X2 = 20, 所以第二个人的随机范围同样是(0,20 ),平均可以抢到10元。

假设第二个人随机到10元,那么剩余金额是90-10 = 80 元。

80/8X2 = 20, 所以第三个人的随机范围同样是(0,20 ),平均可以抢到10元。

以此类推,每一次随机范围的均值是相等的。

// 发红包算法,金额参数以分为单位
    public static List<Integer> divideRedPackage(Integer totalAmount,
            Integer totalPeopleNum) {

        List<Integer> amountList = new ArrayList<Integer>();

        Integer restAmount = totalAmount;

        Integer restPeopleNum = totalPeopleNum;

        Random random = new Random();

        for (int i = 0; i < totalPeopleNum - 1; i++) {

            // 随机范围:[1,剩余人均金额的两倍),左闭右开

            int amount = random.nextInt(restAmount / restPeopleNum * 2 - 1) + 1;
            restAmount -= amount;
            restPeopleNum--;
            amountList.add(amount);
        }
        amountList.add(restAmount);

        return amountList;
    }

    public static void main(String[] args) {

        List<Integer> amountList = divideRedPackage(5000, 30);

        for (Integer amount : amountList) {

            System.out.println("抢到金额:" + new BigDecimal(amount).divide(new BigDecimal(100)));
        }
    }

程序输出结果如下:

抢到金额:2.92

抢到金额:1.48

抢到金额:3.05

抢到金额:0.53

抢到金额:0.45

抢到金额:1.36

抢到金额:1.02

抢到金额:1.99

抢到金额:1.3

抢到金额:0.48

抢到金额:0.83

抢到金额:2.89

抢到金额:0.94

抢到金额:2.11

抢到金额:3.13

抢到金额:0.91

抢到金额:2.64

抢到金额:2.02

抢到金额:2.88

抢到金额:1.13

抢到金额:2.09

抢到金额:1.37

抢到金额:2.41

抢到金额:2.13

抢到金额:1.32

抢到金额:0.44

抢到金额:1.62

抢到金额:1.89

抢到金额:2.23

抢到金额:0.44

猜你喜欢

转载自blog.csdn.net/qq_35393472/article/details/80073948