之前也跟一些讨论过随机红包分配这个问题,自己想了几个方案,但感觉都不太合理,比如无法保证每个人都能得到,以及每个人的期望都一样等等。
在知乎上看到有人说是问过微信的人,大致是随机范围为0.01~当前期望*2之间。于是实现了一下,并做了一些简单的探究。
public class HongBao {
public static final int NUM = 20;
public static final BigDecimal AMOUNT = new BigDecimal(200);
public static final BigDecimal MIN_VALUE = new BigDecimal(0.01);
public static final int SCALE = 2;
public static final int MODE = BigDecimal.ROUND_UP;
public static final int RUN = 5000;
public static void main(String[] args) {
BigDecimal[] array = new BigDecimal[NUM];
for (int i = 0; i < NUM; i++) {
array[i] = BigDecimal.ZERO;
}
for (int run = 0; run < RUN; run++) {
BigDecimal remain = AMOUNT.setScale(SCALE, MODE);
// BigDecimal total = BigDecimal.ZERO.setScale(SCALE, MODE);
BigDecimal bestAmount = BigDecimal.ZERO;
int bestPosition = 0;
for (int i = 0; i < NUM; i++) {
BigDecimal current;
if (i == NUM - 1) {
current = remain;
// total = total.add(remain);
// System.out.println(remain.toString());
// System.out.println("total:" + total.toString());
} else {
BigDecimal max = remain.divide(new BigDecimal(NUM - i), SCALE, MODE).multiply(new BigDecimal(2));
current = max.subtract(MIN_VALUE).multiply(new BigDecimal(Math.random())).add(MIN_VALUE)
.setScale(SCALE, MODE);
// total = total.add(current);
// System.out.println(current.toString() + "max:" +
// max.toString());
}
remain = remain.subtract(current);
array[i] = array[i].add(current);
if (current.compareTo(bestAmount) == 1) {
bestAmount = current;
bestPosition = i;
}
}
System.out.println(bestPosition + "," + bestAmount.toString());
}
for (int i = 0; i < NUM; i++) {
//System.out.println(array[i].toString());
}
}
}
以200块发20份为例,一次的结果如下:
运行1000次的结果,每个人的期望为200/20*1000=10000,大致没有问题
最佳手气
一般大家比较好奇的是在第几位开红包,容易出大的。在平常收发红包的过程中,感觉大红包一般都是在后面出现概率较高。
由于数学推导我完全不懂,那么我就拿程序也来做做测试,运行1000次,看看第几次开为最佳手气
从这里看到是后面的会大一些,与平常的感觉类似,那再看看2000次的
嗯,依旧是靠后的获得最佳的会多一些,并且后面和前面的差距也比较大了。峰值居然还是出现在了倒数第二次
不信邪,继续5000次
中间波谷,两头波峰的情况已经有点显现
最后试试30000次,其实没有太大区别了,基本的走势是一致的,中部低,尾部高。
下面是10人5000次与30人15000次
基本的趋势没有变化, 并且人数越多的情况下,波峰会越明显,那么是不是可以说,想要多拿手气最佳,最后两次拿就行了呢。
还得补充一下,手气最佳并不是代表最赚,如果每次都是最后两次拿的话,总的金额也都差不多的,即看第二张图期望其实是一样的。
怎样赚
平常最常玩的就是大家抢完后,最佳手气的再发。以这个为前提,进行一下探索。
首先,第一个拿的人,随机范围是0.01~期望*2,并且此时期望为整体期望,所以其分布应该是最为平均的。(测试10000次,分为20个金额区间统计,则每个区间数量大约为500个)
但是后面拿的人会受到前面的人拿的影响,总体期望虽然一致,但可能在分布上并不是那么均匀。
直接模拟最佳手气的人继续发的场景,最后成果如下:
所以,大家都应该明白怎么做了吧