红包随机分配问题php,红包的随机分配算法

网站换成了HTTPS访问,比以前有逼格了。顺应潮流的使用了Let's encrypt。

最近偶然间想到了红包的分配问题,在这里记录下思路和代码。

问题

发一个N元红包,M人来分,尽量公平每个人拿到的金额。

思路:假设10元红包10个人分,为了保证剩下的人能拿到红包,每个人最大能拿(红包金额-剩余人数*最小金额)的量,但如果每个人都可能拿最大金额,对排在后面的人就不公平,为此需要对取值范围进行调整。

代码一var RedPacket = function(person,money,min){

this.person = person; //人数

this.money = money; //红包金额

this.min = min; //最小金额

this.random = 0; //每次抽到的金额

this.algorithm1 = function(){

for(let i=1;i

let max = this.money-(this.person-i)*min;

let avg;

if(i!=this.person-1){

do{

avg = max/(this.person-i)+[max/(this.person-i)]*(1/2); //取值范围公式

}while(avg>max)

}else{

avg = max;

}

do{

this.random = parseFloat(Math.random()*(avg-min)+min); //抽取avg和min之间的随机数

this.random = Math.floor(this.random*Math.pow(10,2))/Math.pow(10,2); //保留小位数

}while(this.random>avg||this.random

this.money = Math.floor((this.money-this.random)*Math.pow(10,2))/Math.pow(10,2);

console.log("第"+i+"个人拿到了"+this.random+"元钱,还剩"+this.money+"元。");

}

console.log("第"+this.person+"个人拿到了最后的"+this.money+"元钱。");

};

}

测试结果

9b191e842e9a46473b27bcac95624a63.png

这个方法每次抽取500次后的结果就如图中所示一样,倒数第二个人之前取得的红包金额量都是递进式的,只有最后两名相对公平。

代码二var RedPacket = function(person,money,min){

this.person = person; //人数

this.money = money; //红包金额

this.min = min; //最小金额

this.random = 0; //每次抽到的金额

this.algorithm2 = function(){

for(let i=this.person;i>1;i--){

let max = this.money-(this.person-1)*this.min;

let avg = i<=2?max:max/i*2; //取值范围公式

do{

this.random = parseFloat(Math.random()*(avg-this.min)+this.min); //抽取avg和min之间的随机数

this.random = Math.floor(this.random*Math.pow(10,2))/Math.pow(10,2);

}while(this.random>avg||this.random

this.money = Math.floor((this.money-this.random)*Math.pow(10,2))/Math.pow(10,2);

console.log("第"+(this.person-i+1)+"个人拿到了"+this.random+"元钱,还剩"+this.money+"元。");

}

console.log("第"+this.person+"个人拿到了最后的"+this.money+"元钱。");

};

}

测试结果

d5b28b81eab2a06584fe8a6d2e0d1242.png

第二种方法就相对平稳了很多,极差小了不少,不过我多次抽取几组后,发现最后一个人还是更容易抽的多些,但如果抽上千次来看的话还是很平均的。

测试地址

多次抽取的话,可以在控制台循环调用method(1)或method(0)方法,分别对应第一个和第二个算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值