▲ x轴为抢的顺序,y轴为该次抢到金额的概率均值
从以上两张图的均值结果可以看出,这个算法中每一次能抢到的金额几率几乎是均等的,从随机性来说比较合理。
5、微信红包算法模拟实现2(含代码)我对随机算法很感兴趣,正巧最近研究的方向有点偏随机数这块,所以也自己实现了一下微信的红包分发算法(算法要点参考的是本文第三节内容)。(注:本节内容引用自《微信红包算法的分析》一文)
5.1、代码实现从第三节中可以了解到,微信并不是一开始就预分配所有的红包金额,而是在拆时进行计算的。这样做的好处是效率高,实时性。本次的代码中,红包具体是怎么计算的呢?请参见第4节中的“关于分配算法,红包里的金额怎么算?为什么出现各个红包金额相差很大?”。
那基于这个思想,可以写出一个红包分配算法:
/**
* 并不完美的红包算法
*/
public static double rand(double money, int people, List l) {
if(people == 1) {
double red = Math.round(money * 100) / 100.0;
l.add(red);
return0;
}
Random random = newRandom();
double min = 0.01;
double max = money / people * 2.0;
double red = random.nextDouble() * max;
red = red <= min ? min : red;
red = Math.floor(red * 100) / 100.0;
l.add(red);
double remain = Math.round((money – red) * 100) / 100.0;
return remain;
}
算法整体思路很简单,就在在最后一个人的时候要注意,此时不进行随机数计算,而是直接将剩余金额作为红包。
5.2、第一次分析采用上述算法,可以对用户的抢红包行为做分析。这里的模仿行为是:30 元的红包,10 人抢。操作 100 次。
可以得出如下结果:
▲ x轴为抢的顺序,y轴为该次抢到金额
从上图中可以很轻易的看出来,越后抢的人,风险越大,同时收益也越大,有较大几率获得“手气最佳”。
那红包面值的分布性如何呢?
▲ x轴为抢的顺序,y轴为该次抢到金额重复 100 次后的平均值
从上图可以看出,都是比较接近平均值(3 元)的。
那重复 1000 次呢?
▲ x轴为抢的顺序,y轴为该次抢到金额重复 1000 次后的平均值
更接近了。。。
可以看出,这个算法可以让大家抢到红包面额在概率上是大致均等的。
5.3、不足之处有人提出了这个问题:
他接下来放了好几张他试验的截图。我这里取了一张,如果有兴趣,可以去知乎的问题里查看更多图片。
而此时,我哥们在和我的在讨论中,也告诉我,确实存在某个规律,可能让最后一个抢的人占有某些微小的优势,比如,多 0.01 的之类。
例如发 6 个,总额 0.09 的包,最后一个抢的有极大概率是 0.03。