微信红包算法(最后一个人抢到的红包比平均值小的可能性非常大!!!)

先上结果:
按照传闻的微信官方的抢红包算法,模拟 五个人,总共五块钱重复抢100000次,平均下来,最后抢的那个人,抢到的红包为
在这里插入图片描述
下面上三种抢红包算法

方法一

0到总钱取随机值,然后总钱减去随机值,作为下次随机的总钱,以此类推,随机值即为抽到的红包数。
很明显,这种算法是不合适的

方法二(微信官方)

抽到的money=(0.01 + Math.random() *(总钱/ 目前人数x2))
这样的话,除了最后一个人之外,前面的人的红包大小概率都是均衡的,但是最后一个人就不一样,他有可能抽到前面的人抽不到的特大红包,但是他抽到小红包的概率会很大。

public void secondMethod(float totalMoney, int num) {
		float money;
		for (int i = 0; i < num; i++) {

			if (i == num - 1) {
				money = totalMoney;
			} else {
				money = (float) (0.01 + Math.random() * (totalMoney / (num - i) * 2));
			}
			DecimalFormat df = new DecimalFormat("0.00");
			String str = df.format(money);
			money = Float.parseFloat(str);
			totalMoney = totalMoney - money;
			
			System.out.println(money);
		}
	}

这是20人抽取五块钱红包的情况,平均每人0.25
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

方法三

一种更加公平且随机的方法:
把总钱进行随机分割,割成人数份

public void thirdMethod(float totalMoney, int num) {
		float money;
		ArrayList list = new ArrayList<>();
		for (int i = 0; i < num-1; i++) {
			money = (float) (0.01 + Math.random() * totalMoney );
			DecimalFormat df = new DecimalFormat("0.00");
			String str = df.format(money);
			money = Float.parseFloat(str);
			if (list.contains(money)) {
				i--;
			} else {
				list.add(money);
			}
		}
		Collections.sort(list);
		for(int i =0;i<list.size()-1;i++){
			float M = (float)list.get(i+1)-(float)list.get(i);
			DecimalFormat df = new DecimalFormat("0.00");
			String str = df.format(M);
			M = Float.parseFloat(str);
			System.out.println(M);
		}
		float M = totalMoney-(float)list.get(list.size()-1);
		DecimalFormat df = new DecimalFormat("0.00");
		String str = df.format(M);
		
		System.out.println(str);
	}

还是20人抽取五块钱红包的情况,平均每人0.25
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

总结:虽然最后抢的人可能会抢到更大一点的红包,但是抢到小红包的概率还是很大的,并且你能保证你刚好是最后一个人?(面临着抢不到红包的风险)。

综上所述,抢红包还是先下手为强!!!

发布了45 篇原创文章 · 获赞 14 · 访问量 2477

猜你喜欢

转载自blog.csdn.net/qq_44357371/article/details/103115263