小玩意 - 抢红包算法(公平版 & 手速版)

简介: 小玩意 - 抢红包算法(公平版 & 手速版)


当我们在群里抢红包时真的是手速越快红包金额越大吗?

image.png

答案:当然是并不是,都说了是拼手气,岂能是拼手速!不过也可以有拼手速的方法。

20210112095826754.gif

二倍均值法(公平版)

这是一种很合理很公平的抢红包算法了,绝对不会让你拼手速的,就别天真了。

在此我们假设

红包剩余金额为 M

红包剩余数量为 N

这种算法就是每次都在区间[0,M/N×2] 随机取一个数

假设100元红包发10个人,那么合理的做法应该是每个人领到10元的概率相同。

第一个人随机金额的范围为[0,100/10×2] ,也就是[0,20],这样平均可以领到10元,此时剩余金额为100-10=90。

第二个人随机金额的范围为[0,90/9×2] ,也就是[0,20],这样平均也可以领到10元,此时剩余金额为90-10=80。

第三个人随机金额的范围为[0,80/8×2] ,也就是[0,20],这样平均也可以领到10元。

这样推导下去,每个人领到相同金额的概率应该就是相同的了。

代码

publicstaticList<Double>doubleMeanMethod(doublemoney,intnumber) {
List<Double>result=newArrayList<Double>();
if(money<0&&number<1)
returnnull;
doubleamount,sum=0;
intremainingNumber=number;
inti=1;
while(remainingNumber>1){
amount=nextDouble(0.01,2*(money/remainingNumber));
sum+=amount;
System.out.println("第"+i+"个人领取的红包金额为:"+format(amount));
money-=amount;
remainingNumber--;
result.add(amount);
i++;
    }
result.add(money);
System.out.println("第"+i+"个人领取的红包金额为:"+format(money));
sum+=money;
System.out.println("验证发出的红包总金额为:"+format(sum));
returnresult;  
}

运行结果

image.png

线段切割法(手速版)

这就是拼手速了,是时候展示手速了。

image.png

这个算法可以把总金额想象成一条线段,每个人都有机会切一刀,前面的人切剩下的后面的人再接着切,这样越是前面的人截取的长度(理解成领取到的红包金额)越大的概率就越大。

代码

publicstaticvoidlineSegmentCutting(doublemoney,intnumber) {
if(money<0&&number<1)
System.out.println("输入错误!");
doublebegin=0,end=money;
doubley=0;
for(inti=0;i<number-1;i++){
doublenn=0;
doubleamount=nextDouble(begin,end);
nn=amount-begin;
System.out.println("第"+(i+1)+"个人领取的红包金额为:"+format(nn));
y+=nn;
begin=amount;
    }
System.out.println("第"+number+"个人领取的红包金额为:"+format(end-begin));
y+=(end-begin);
System.out.println("验证发出的红包总金额为:"+format(y));
}

运行结果

image.png

完整代码

packagecom.zhl.blogTest;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.Random;
importjava.util.Scanner;
publicclassredEnvelope {
/*Random 随机生成一个区间在[min , max]的数值randNumber 将被赋值为一个 MIN 和 MAX 范围内的随机数int randNumber =rand.nextInt(MAX - MIN + 1) + MIN; *//*** 生成min到max范围的浮点数**/publicstaticdoublenextDouble(finaldoublemin, finaldoublemax) {
returnmin+ ((max-min) *newRandom().nextDouble());
    }
publicstaticStringformat(doublevalue) {
returnnewjava.text.DecimalFormat("0.00").format(value); // 保留两位小数        }
// 二倍均值法publicstaticList<Double>doubleMeanMethod(doublemoney,intnumber){
List<Double>result=newArrayList<Double>();
if(money<0&&number<1)
returnnull;
doubleamount,sum=0;
intremainingNumber=number;
inti=1;
while(remainingNumber>1){
amount=nextDouble(0.01,2*(money/remainingNumber));
sum+=amount;
System.out.println("第"+i+"个人领取的红包金额为:"+format(amount));
money-=amount;
remainingNumber--;
result.add(amount);
i++;
        }
result.add(money);
System.out.println("第"+i+"个人领取的红包金额为:"+format(money));
sum+=money;
System.out.println("验证发出的红包总金额为:"+format(sum));
returnresult;
    }
// 线段切割法publicstaticvoidlineSegmentCutting(doublemoney,intnumber){
if(money<0&&number<1)
System.out.println("输入错误!");
doublebegin=0,end=money;
doubley=0;
for(inti=0;i<number-1;i++){
doublenn=0;
doubleamount=nextDouble(begin,end);
nn=amount-begin;
System.out.println("第"+(i+1)+"个人领取的红包金额为:"+format(nn));
y+=nn;
begin=amount;
        }
System.out.println("第"+number+"个人领取的红包金额为:"+format(end-begin));
y+=(end-begin);
System.out.println("验证发出的红包总金额为:"+format(y));
    }
publicstaticvoidmain(String[] args) {
Scannersc=newScanner(System.in);
System.out.println("这是一段模拟抢红包的代码。");
intnumber;
doublemoney;
System.out.print("请输入红包总金额:");
money=sc.nextDouble();
System.out.print("请输入红包数量:");
number=sc.nextInt();
//System.out.println(money + " " + number);//二倍均值法doubleMeanMethod(money,number);
//System.out.println(doubleMeanMethod(money,number).toString());//也是可以直接输出list的,为了观察方便,我就在循环中输出了,存在list里主要是为了后续方便数据的使用System.out.println();
//线段切割法lineSegmentCutting(money,number);   
    }
}
目录
相关文章
|
缓存 算法 数据管理
基于改进Slime Mold算法的多处理器公平调度
基于改进Slime Mold算法的多处理器公平调度
64 0
|
机器学习/深度学习 人工智能 缓存
基于改进Slime Mold算法的多处理器公平调度
基于改进Slime Mold算法的多处理器公平调度 常州大学计算机科学与人工智能学院,常州213164 * 通信地址应为的作者。 † 这些作者对这项工作做出了同样的贡献。 算法2023,16(10),473;https://doi.org/10.3390/a16100473(注册DOI) 接收日期:2023年9月25日/修订日期:2023.10月4日/接受日期:2024.10月7日 (本文属于《可持续制造的特刊调度理论与算法》)
94 0
基于改进Slime Mold算法的多处理器公平调度
|
算法 C# Windows
C# 实现抢红包算法
C# 实现抢红包算法
134 0
抢红包算法(公平版和手速版)
抢红包有两种算法:二倍均值法(公平版)和线段切割法(手速版)
抢红包算法(公平版和手速版)
|
算法
为啥春节抢红包总不是手气最佳?看完微信抢红包算法你就明白了!
春节必不可少的活动就是抢红包啦,从以前的纸质红包到现在互联网红包(以微信红包为首),今天我们就来分析一下抢红包的算法,其中有一些是微信红包的算法,看完你就知道手气最佳是如何产生的啦!
457 0
为啥春节抢红包总不是手气最佳?看完微信抢红包算法你就明白了!
|
算法
漫画:如何实现抢红包算法?
发出一个固定金额的红包,由若干个人来抢,需要满足哪些规则?所有人抢到金额之和等于红包金额,不能超过,也不能少于。每个人至少抢到一分钱。要保证所有人抢到金额的几率相等。
189 0
漫画:如何实现抢红包算法?
|
算法 开发者
算法笔试模拟题精解之“公平”
可以先求出两个小朋友初始的糖的数量差 diff,如果 diif 为0,则发糖次数为0。
算法笔试模拟题精解之“公平”
|
算法 机器学习/深度学习
抢红包的红包生成算法
过年微信红包很火,最近有个项目也要做抢红包,于是写了个红包的生成算法。 红包生成算法的需求 预先生成所有的红包还是一个请求随机生成一个红包 简单来说,就是把一个大整数m分解(直接以“分为单位,如1元即100)分解成n个小整数的过程,小整数的范围是[min, max]。
1314 0
|
22天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
7天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。