原文地址:原文地址

算法

算法很简单,不是提前算好,而是抢红包时计算:

红包里的金额怎么算?为什么出现各个红包金额相差很大?
答:随机,额度在0.01和剩余平均值*2之间。

实现

实现上述算法的逻辑主要是:

public static double getRandomMoney(RedPackage _redPackage) {    // remainSize 剩余的红包数量
    // remainMoney 剩余的钱
    if (_redPackage.remainSize == 1) {
        _redPackage.remainSize--;        return (double) Math.round(_redPackage.remainMoney * 100) / 100;
    }
    Random r     = new Random();    double min   = 0.01; //
    double max   = _redPackage.remainMoney / _redPackage.remainSize * 2;    double money = r.nextDouble() * max;
    money = money <= min ? 0.01: money;
    money = Math.floor(money * 100) / 100;
    _redPackage.remainSize--;
    _redPackage.remainMoney -= money;    return money;
}

LeftMoneyPackage数据结构如下:

class RedPackage {
    int    remainSize;
    double remainMoney;
}

测试时初始化相关数据是:

static void init() {
    redPackage.remainSize  = 30;
    redPackage.remainMoney = 500;
}

测试结果

单词测试随机红包

以上面的初始化数据(30人抢500块),执行了两次,结果如下:

// 第一次

15.69 21.18 24.11 30.85 0.74 20.85 2.96 13.43 11.12 24.87 1.86 19.62 5.97 29.33 3.05 26.94 18.69 34.47 9.4 29.83 5.17 24.67 17.09 29.96 6.77 5.79 0.34 23.89 40.44 0.92

// 第二次

10.44 18.01 17.01 21.07 11.87 4.78 30.14 32.05 16.68 20.34 12.94 27.98 9.31 17.97 12.93 28.75 12.1 12.77 7.54 10.87 4.16 25.36 26.89 5.73 11.59 23.91 17.77 15.85 23.42 9.77

对应图表如下:

还有一张:


多次均值

重复执行200次的均值

重复执行2000次的均值

可以看到,这个算法可以让大家抢到的红包面额在概率上是大致均匀的。