现在微信、QQ等社交软件,有很多小应用,红包算是一个高频的应用,对于普通人来说,抢红包无论抢到了几毛,还是几块,都会让人有种刺激的赶脚。
但红包是如何分配的?先抢到和后抢到,真的有什么区别?这是个有意思的话题,“程序员小灰”的一篇文章《漫画:如何实现抢红包算法?》,介绍了一些红包算法,为我们揭开端倪,
方案一:
1. 每次随机,随机的上限是剩余的红包金额。
2. 每次抢到的金额=随机取件(0, 剩余金额)。
缺点:因为是随机的,所以先抢的人有很大优势,越往后的人随机到的平均金额越小。
假设有10个人,红包总额100元。
第一个人的随机范围是(0,100元),平均可以抢到50元。
假设第一个人随机到50元,那么剩余金额是100-50 = 50 元。
第二个人的随机范围是 (0, 50元),平均可以抢到25元。
假设第二个人随机到25元,那么剩余金额是50-25 = 25 元。
第三个人的随机范围是 (0, 25元),平均可以抢到12.5元。
以此类推,每一次随机范围越来越小。
方案二:
二倍均值法,每次随机金额的上限设为剩余人均金额的二倍。
剩余红包金额为M,剩余人数为N,那么有如下公式:
每次抢到的金额 = 随机区间 (0, M / N X 2)
这个公式,保证了每次随机金额的平均值是相等的,不会因为抢红包的先后顺序而造成不公平。
假设有10个人,红包总额100元。
100/10X2 = 20, 所以第一个人的随机范围是(0,20 ),平均可以抢到10元。
假设第一个人随机到10元,那么剩余金额是100-10 = 90 元。
90/9X2 = 20, 所以第二个人的随机范围同样是(0,20 ),平均可以抢到10元。
假设第二个人随机到10元,那么剩余金额是90-10 = 80 元。
80/8X2 = 20, 所以第三个人的随机范围同样是(0,20 ),平均可以抢到10元。
以此类推,每一次随机范围的均值是相等的。
缺点:除了最后一次,任何一次抢到的金额都要小于人均金额的两倍,并不是任意的随机。
代码实现如下,
public class RedPackage {
public static List divideRedPackage (int totalAmount, int totalPersonNum) {
List amountList = new ArrayList();
int restAmount = totalAmount;
int restPersonNum = totalPersonNum;
Random random = new Random();
for (int i = 0; i < totalPersonNum - 1; i++) {
int amount = random.nextInt((restAmount / restPersonNum) * 2 - 1) + 1;
restAmount -= amount;
restPersonNum--;
amountList.add(Integer.valueOf(amount));
}
amountList.add(restAmount);
return amountList;
}
public static void main(String[] args) {
List amountList = divideRedPackage(100, 20);
int i = 1;
int total = 0;
for (Integer mount : amountList) {
total += mount;
System.out.println("[" + i + "] 抢到金额: " + mount + " 累积: " + total);
i++;
}
}
输出如下,可以看出,基本是随机的,
[1] 抢到金额: 5 累积: 5
[2] 抢到金额: 7 累积: 12
[3] 抢到金额: 1 累积: 13
[4] 抢到金额: 1 累积: 14
[5] 抢到金额: 7 累积: 21
[6] 抢到金额: 5 累积: 26
[7] 抢到金额: 2 累积: 28
[8] 抢到金额: 5 累积: 33
[9] 抢到金额: 1 累积: 34
[10] 抢到金额: 7 累积: 41
[11] 抢到金额: 4 累积: 45
[12] 抢到金额: 5 累积: 50
[13] 抢到金额: 2 累积: 52
[14] 抢到金额: 10 累积: 62
[15] 抢到金额: 10 累积: 72
[16] 抢到金额: 7 累积: 79
[17] 抢到金额: 7 累积: 86
[18] 抢到金额: 3 累积: 89
[19] 抢到金额: 7 累积: 96
[20] 抢到金额: 4 累积: 100
当然,还会有其他算法,欢迎朋友们提出,让我们开开眼界。
虽然不知道微信、QQ采用了何种算法,但以上两种算法,至少可以提供一些想法,以前上学的时候,学这个学那个,有时可能不知道,除了考试,还有何用?其实实际生活中,很多你可能忽略的地方,都蕴含着以前我们学过、了解、甚至听说的道理、知识,就看细心的你,能不能发现这些,能不能学其所用,用其所学。
如果您觉得本文有帮助,欢迎关注转发:bisal的个人杂货铺,