互联网|最全解密微信红包随机算法( 五 )


他接下来放了好几张他试验的截图 。 我这里取了一张 , 如果有兴趣 , 可以去知乎的问题里查看更多图片 。
互联网|最全解密微信红包随机算法
本文插图


而此时 , 我哥们在和我的在讨论中 , 也告诉我 , 确实存在某个规律 , 可能让最后一个抢的人占有某些微小的优势 , 比如 , 多 0.01 的之类 。
例如发 6 个 , 总额 0.09 的包 , 最后一个抢的有极大概率是 0.03 。
互联网|最全解密微信红包随机算法
本文插图

然而我之前的代码却没办法体现出这一点 。
比如 10 人拆 0.11 元的包 , 我的结果是:
互联网|最全解密微信红包随机算法
本文插图

可见以上代码还存在不足之处 。
于是我就有一个猜测:
微信可能不是对全金额进行随机的 , 可能在派发红包之前 , 已经对金额做了处理 , 比如 , 事先减去(红包个数*0.01) , 之后在每个红包的随机值基础上加 0.01 , 以此来保证每个红包最小值都是 0.01 。
这个猜测或许可以解开那位知友和我哥们这边的疑惑 。
5.4、完善算法
在原先的基础上对代码进行简单的修正:
public static double rand(double money, int people, Listl) {if(people == 1) {double red = Math.round(money * 100) / 100.0l.add(red+0.01)return 0}Random random = newRandom()double min = 0double max = money / people * 2.0double red = random.nextDouble() * maxred = red &lt= min ? min : redred = Math.floor(red * 100) / 100.0l.add(red+0.01)double remain = Math.round((money - red) * 100) / 100.0return remain}
这个算法 , 在第一次调用时传入 money 的值是总金额减去红包数*0.01 , 大概像这样:
_money = _money - people * 0.015.5、第二次分析
5.5.1 验证上次的不足之处
1)10 人抢 0.11 元的包:
互联网|最全解密微信红包随机算法
本文插图

2)2 人抢 0.03 元的包:
互联网|最全解密微信红包随机算法
本文插图

3)6 人抢 0.09 的包:
互联网|最全解密微信红包随机算法
本文插图

5.5.2 修改后的代码会不会对已知结论造成影响?
30 元的红包 , 10 人抢 , 操作 100 次 。
互联网|最全解密微信红包随机算法
本文插图

▲ x轴为抢的顺序 , y轴为该次抢到金额
互联网|最全解密微信红包随机算法
本文插图

▲ x轴为抢的顺序 , y轴为该次抢到金额重复 100 次后的平均值

由上面两图可见 , 结论基本上没有改变 。
5.6、结论
经过上述代码实践可知:
1)先抢后抢 , 金额期望都是相同的;2)微信的红包算法很可能是预先分配给每人 0.01 的“底额”;3)后抢者风险高 , 收益大 。5.7、补充
互联网|最全解密微信红包随机算法
本文插图

互联网|最全解密微信红包随机算法
本文插图

大家也可以试试 。
以上 , 大概可以证明 , 微信红包是在分配前先给每个人 0.01 的最低金额的!
6、参考资料[1] 微信红包随机算法初探[2] 微信红包算法的分析[3] 微信红包的架构设计简介[4] 微信红包的随机算法是怎样实现的?另外 , 知乎上对于微信红包算法的讨论问题很多人参与 , 有兴趣可以上去看看 , 或许会有更多启发:《微信红包的随机算法是怎样实现的?》 。


推荐阅读