search
HomeBackend DevelopmentPHP Tutorial大家在抢红包,程序员在研究红包算法_PHP

除夕全天微信用户红包总发送量达到10.1亿次,摇一摇互动量达到110亿次,红包峰值发送量为8.1亿次/分钟。

抛开微信红包的市场价值不谈,红包本身的算法也引发了热议,由于官方没有给出明确的说法,各家也是众说纷纭,小编下面也为大家带来几种分析。

首先看看数据分析帝

大多数人都做出自己的猜测,这也是在不知道内部随机算法的时候的唯一选择,但是大多数人没有给出自己亲自的调查结果。这里给出一份100样本的调查抽样样本数据,并提出自己的猜测。

1. 钱包钱数满足截尾正态随机数分布。大致为在截尾正态分布中取随机数,并用其求和数除以总价值,获得修正因子,再用修正因子乘上所有的随机数,得到红包价值。

这种分布意味着:低于平均值的红包多,但是离平均值不远;高于平均值的红包少,但是远大于平均值的红包偏多。


图1. 钱包价值与其频率分布直方图及其正态拟合

但看分布直方图并不能推出它符合正态分布,但是考虑到程序的简洁性和随机数的合理性,这是最合乎情理的一种猜测。
越是后面的钱包,价值普遍更高


图2. 钱包序列数与其价值关系曲线

从图2中的线性拟合红线可以看到,钱包价值的总体变化趋势是在慢慢增大,其变化范围大约是一个绿色虚线上下界划出的“通道”。(曲线可以被围在这么一个正合乎常规的“通道”中,也从侧面反映了规律1的合理性,说明了并不是均匀分布的随机数)
从另一个平均数的图中也可以看出这一规律。


图3. 平均数随序列数的变化曲线

在样本中,1000价值的钱包被分成100份,均值为10。然而在图3中我们可以看到在最后一个钱包之前,平均数一直低于10,这就说明了一开始的钱包价值偏低,一直被后期的钱包价值拉着往上走,后期的钱包价值更高。

3. 当然平均数的图还可以透露出另一个规律,那就是最后的那一个人往往容易走运抽得比较多。因为最后那一个人是钱包剩下多少就拿多少的,而之前所有人的平均数 都低于10,所以至少保证了最后一个人会高于平均值。在本样本中,98号钱包抽到35,而最后一份钱包抽到46。

综上,根据样本猜测:


1. 抽到的钱大多数时候跟别人一样少,但一旦一多,就容易多很多。
2. 越是抽后面的钱包,钱越容易多。
3. 最后一个人往往容易撞大运。

点评:这种明显很实际有差异,小编每次不管什么时候抢都是几毛钱。

第二位同学写了一个简单python 代码

据观察,红包分钱满足以下几点:

1.不会有人拿不到钱

2.不会提前分完

3.钱的波动范围很大

红包在一开始创建的时候,分配方案就订好了。抢红包的时候,不过是挨个pop up而已。

因此 python 代码如下:

def weixin_divide_hongbao(money, n): 
divide_table = [random.randint(1, 10000)
for x in xrange(0, n)] 
sum_ = sum(divide_table) 
return [x*money/sum_ for x in divide_table] 

不过上述算法还有两个小问题:

1.浮点数精度问题

2.边界值的处理

第三位同学按照网上流传的python写了一个java的版本

int j=1; 
while(j<1000) 
{ 
int number=10; 
float total=100; 
float money; 
double min=0.01; 
double max; 
int i=1; 
 
List math=new ArrayList(); 
while(i<number) 
{ 
 
max = total- min*(number- i); 
int k = (int)((number-i)/2); 
if (number -i <= 2) 
{k = number -i;} 
max = max/k; 
money=(int)(min*100+Math.random()*(max*100-min*100+1)); 
money=(float)money/100; 
total=total-money; 
math.add(money); 
System.out.println("第"+i+"个人拿到"+money+"剩下"+total); 
i++; 
if(i==number) 
{ 
math.add(total); 
System.out.println("第"+i+"个人拿到"+total+"剩下0"); 
} 
} 
 
System.out.println("本轮发红包中第"+(math.indexOf(Collections.max(math))+1)+"个人手气最佳"); 
j++; 
}

第四位同学的这种算法看起来非常科学。

他认为:

1、每个人都要能够领取到红包;

2、每个人领取到的红包金额总和=总金额;

3、每个人领取到的红包金额不等,但也不能差的太离谱,不然就没趣味;

4、算法一定要简单,不然对不起腾讯这个招牌;

正式编码之前,先搭建一个递进的模型来分析规律

设定总金额为10元,有N个人随机领取:

N=1

则红包金额=X元;

N=2

为保证第二个红包可以正常发出,第一个红包金额=0.01至9.99之间的某个随机数

第二个红包=10-第一个红包金额;

N=3

红包1=0.01至0.98之间的某个随机数

红包2=0.01至(10-红包1-0.01)的某个随机数

红包3=10-红包1-红包2

……

int j=1; 
while(j<1000) 
{ 
int number=10; 
float total=100; 
float money; 
double min=0.01; 
double max; 
int i=1; 
 
List math=new ArrayList(); 
while(i<number) 
{ 
 
max = total- min*(number- i); 
int k = (int)((number-i)/2); 
if (number -i <= 2) 
{k = number -i;} 
max = max/k; 
money=(int)(min*100+Math.random()*(max*100-min*100+1)); 
money=(float)money/100; 
total=total-money; 
math.add(money); 
System.out.println("第"+i+"个人拿到"+money+"剩下"+total); 
i++; 
if(i==number) 
{ 
math.add(total); 
System.out.println("第"+i+"个人拿到"+total+"剩下0"); 
} 
} 
 
System.out.println("本轮发红包中第"+(math.indexOf(Collections.max(math))+1)+"个人手气最佳"); 
j++; 
} 

输入一看,波动太大,这数据太无趣了!

第1个红包:7.48 元,余额:2.52 元

第2个红包:1.9 元,余额:0.62 元

第3个红包:0.49 元,余额:0.13 元

第4个红包:0.04 元,余额:0.09 元

第5个红包:0.03 元,余额:0.06 元

第6个红包:0.03 元,余额:0.03 元

第7个红包:0.01 元,余额:0.02 元

第8个红包:0.02 元,余额:0 元

改良一下,将平均值作为随机安全上限来控制波动差

int j=1; 
while(j<1000) 
{ 
int number=10; 
float total=100; 
float money; 
double min=0.01; 
double max; 
int i=1; 
 
List math=new ArrayList(); 
while(i<number) 
{ 
 
max = total- min*(number- i); 
int k = (int)((number-i)/2); 
if (number -i <= 2) 
{k = number -i;} 
max = max/k; 
money=(int)(min*100+Math.random()*(max*100-min*100+1)); 
money=(float)money/100; 
total=total-money; 
math.add(money); 
System.out.println("第"+i+"个人拿到"+money+"剩下"+total); 
i++; 
if(i==number) 
{ 
math.add(total); 
System.out.println("第"+i+"个人拿到"+total+"剩下0"); 
} 
} 
 
System.out.println("本轮发红包中第"+(math.indexOf(Collections.max(math))+1)+"个人手气最佳"); 
j++; 
}

输出结果见下图

第1个红包:0.06 元,余额:9.94 元

第2个红包:1.55 元,余额:8.39 元

第3个红包:0.25 元,余额:8.14 元

第4个红包:0.98 元,余额:7.16 元

第5个红包:1.88 元,余额:5.28 元

第6个红包:1.92 元,余额:3.36 元

第7个红包:2.98 元,余额:0.38 元

第8个红包:0.38 元,余额:0 元

小结:

小编觉得这完全可以理解成一个红包引发的血案,小编仅仅列举了几个,还有一些工程学的同学直接抛出了数学模型、离散函数等等,但是无论算法是简单还是复杂,玩的开心就够了。

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
微信红包最大金额能发多少微信红包最大金额能发多少Feb 23, 2024 pm 04:40 PM

微信红包最大金额能发多少?在微信中的红包发送金额是有上限的,有些用户不清楚微信红包最大金额能发多少。在非特殊日期的最大金额是200。接下来就是小编为用户带来的红包最大金额数量的介绍,感兴趣的用户快来一起看看吧!微信使用教程微信状态背景图怎么设置答:200元详情介绍:1、微信红包金额上限:200。每人每次的微信红包最高只能发送200元。2、特殊红包金额:在每年的5月20日,用户可以发送金额上限为520元的红包。

微信红包怎么退回 微信红包怎么拒收立即退还给对方微信红包怎么退回 微信红包怎么拒收立即退还给对方Feb 22, 2024 pm 04:43 PM

现在的微信红包是不支持手动退回的。教程适用型号:iPhone13系统:iOS15.5版本:微信8.0.19解析1现在的微信红包是不支持手动退回的,对于没有领取的微信红包,微信系统会在24小时后自动退回发起账号,所以当我们收到红包后想要退回的话,只要不接受,过了24小时就会自动退回了。补充:微信转账怎么退回1在微信聊天界面点击需要退回的转账。2在转账详情界面中,点击退还选项。3在新出现的弹窗中,再次点击退还即可。总结/注意事项现在的微信红包是不支持手动退回的,当我们收到红包,只要不接受,过了24小

微信红包进行退回的详细步骤微信红包进行退回的详细步骤Mar 25, 2024 am 11:21 AM

1、找到微信小程序:2、点击搜索【腾讯举报受理中心】。3、点击网络诈骗的选项。4、输入相关信息和截图。微信红包说明:1、微信红包24小时未领取,会直接退回。2、微信红包被别人领取,自己是无法退回的;

微信红包怎么退回?微信红包退回的处理方法微信红包怎么退回?微信红包退回的处理方法Mar 12, 2024 pm 05:00 PM

微信是一款集社交、支付、购物等多功能于一体的移动应用,深受用户喜爱。其中,微信红包作为支付功能的一部分,以其便捷性和趣味性赢得了广大用户的青睐。然而,有时我们可能会遇到发错红包的情况。微信红包的退回虽然有时略显麻烦,在使用微信红包时,请务必仔细核对信息,确保每一次的发送都能准确无误。微信红包怎么退回?微信红包退回的处理方法微信红包的退回方式主要取决于红包是否已被领取。如果红包未被领取,有以下处理方式:情况一,如果对方尚未领取红包,可以直接与对方沟通,告知其发错了红包,并请对方不要领取。超过24小

微信红包设置提醒的具体方法微信红包设置提醒的具体方法Mar 25, 2024 pm 05:46 PM

1、下载腾讯管家2、找到腾讯手机管家:【实用工具】-【更多】。3、然后点击【红包闹钟】。4、看到微信和QQ的选项,点击下方一键开启。5、然后就可以看到开启后的界面,也可以点击右上角设置按钮进行设置。6、可以选择声音提醒,震动提醒,都可以设置。

微信红包退回对方有提示的详细讲解微信红包退回对方有提示的详细讲解Mar 25, 2024 pm 05:51 PM

1、首先我们打开微信点击搜索框。2、搜索微信支付3、点击进入。4、在这里双方都会有微信红包退还的提示。

微信红包提示音怎么设置?微信红包提示音设置方法微信红包提示音怎么设置?微信红包提示音设置方法Mar 13, 2024 am 11:30 AM

微信,作为一款功能丰富的社交应用,不仅为人们提供了便捷的沟通方式,还通过其独特的红包功能增添了更多乐趣。而设置微信红包提示音,则能让用户在收到红包时第一时间得知,增添了期待与惊喜。微信红包提示音的设置,让每一次的红包接收都充满了期待与乐趣。微信红包提示音的设置方法主要依赖于你的手机系统和微信版本。以下看看针对安卓和苹果系统的设置步骤吧。微信红包提示音怎么设置?微信红包提示音设置方法一,对于安卓系统设置方法1、打开微信应用,点击底部导航栏的【我】选项,进入【我】页面后再点击【设置】。2、在设置页面

微信红包最多能发多少微信红包最多能发多少Aug 17, 2023 pm 01:48 PM

微信红包最多能发二百。详情介绍:每个用户每天发红包的总金额不能超过1000元。虽然有一些限制,但微信红包仍然是一种非常方便和受欢迎的支付方式。无论是在过年期间还是在其他特殊场合上,微信红包都给人们带来了更多的乐趣和惊喜 。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

Repo: How To Revive Teammates
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor