红包算法

打印 上一主题 下一主题

主题 861|帖子 861|积分 2593

5.红包算法

标题

一个关于钱的需求。
发红包功能,例如一个人的群里发了100红包,群里有10个人一起来抢红包,每个人的金额随机分配。
抢红包规则

  • 所有人抢到的金额之和要等于红包金额。
  • 抢到红包的人至少抢到1分钱。
  • 尽可能保证红包拆分的金额分布均衡,不要出现两极分化太严重的情况。
思路

二倍均值法
假设红包剩余金额为x元,剩余人数y人,有如下公式:抢到的m(金额)=[0.001,x/y * 2 - 0.01]元
这个公式,保证了每次随机金额的均匀值是相称的,不会因为抢红包的先后顺序而造成不公平。
举例
假设有5个人,红包总额100元。
100/5 * 2 - 0.0.1 = 39.9,第一个人抢到的金额随机范围是[0.01,39.9],在数据量多的情况下,接近正态分布,均匀可抢到20元。
80/4 * 2 - 0.01 = 39.9元,假设第2个人随机抢到了20元,那么剩余金额是60元。
60÷3×2 = 40,所以第3个人抢到的金额的随机范围同样是[0.01,39.99]元,均匀可以抢到20元。 以此类推,每一次抢到金额随机范围的均值是相称的。
代码
  1. import java.math.BigDecimal;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.Random;
  5. public class RedPackage {
  6.     /**
  7.      * @param totalAmount    总金额(单位 分)
  8.      * @param totalPeopleNum 总人数
  9.      * @return
  10.      */
  11.     public static List<Integer> divideRedPackage(int totalAmount, int totalPeopleNum) {
  12.         List<Integer> amountList = new ArrayList<>();
  13.         int restAmount = totalAmount;
  14.         int restPeopleNum = totalPeopleNum;
  15.         Random random = new Random();
  16.         for (int i = 0; i < totalPeopleNum - 1; i++) {
  17.             int amount = random.nextInt(restAmount/restPeopleNum * 2 - 1) + 1;
  18.             restAmount -= amount;
  19.             restPeopleNum--;
  20.             amountList.add(amount);
  21.         }
  22.         amountList.add(restAmount);
  23.         return amountList;
  24.     }
  25.     public static void main(String[] args) {
  26.         for(Integer amount : divideRedPackage(10000,10)){
  27.             System.out.println("抢到金额: " + new BigDecimal(amount).divide(new BigDecimal(100)) + "元");
  28.         }
  29.     }
  30. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

篮之新喜

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表