数据结构与算法:趣味算法 —— 红包分配

分配的目标

基于对“公平”的理解,微信红包分配算法基于以下三个目标:

  1. 先后抽到的红包金额期望尽量相等(机会相等);
  2. 所有人抽到金额的基尼系数尽量小(差距较小);
  3. 每个人至少有1分钱;

分配算法

算法思路:假设要将金额为m元的红包发给n个人。当第k个人点开红包时,按照以下规则为其分配金额(假设当前红包剩余金额为x,剩余人数为y)

  1. 为剩余的y-1个人预留1分钱,将余下的钱平分为y份,每份金额为py = (x - 0.01 * (y-1))/y;
  2. 从[0,2*py]的均匀分布中随机选取一个金额xk分配给第k个人;如果金额不足0.01则取0.01,如果金额不是0.01的整数倍,则在百分位向下取整;
  3. 更新剩余金额x = x -xk和剩余人数y=y-1;

分配效果

1、不同人抽到金额的期望相等(m/n),和抢红包顺序无关:

2、先抽的人金额方差小,后抽的人金额方差大(后抽的人更有可能获得非常小或非常大的红包)

第一个人抽到金额从小到大排序(1000次试验):

最后一个人抽到金额从小到大排序:

3、所有人抽到的金额基尼系数近似为0(1000个人)

机会相等的证明

为什么不用简单隔板法

如果只是为了使每个人的期望金额相同,完全可以用另外一种简单算法,生成n-1个0~1之间的随机数,排序后得到一个序列 $A=[0,x1,x_2,…x{n-1},1]$,将 m*(A[i]-A[i-1])分配给第i个人。

适用这种算法会产生较大的“贫富差距”,这一点从洛伦兹曲线上可以看到:

坚持原创技术分享,您的支持将鼓励我继续创作!