手机版

大家都在抢红包 程序员都在研究红包算法

时间:2021-09-08 来源:互联网 编辑:宝哥软件园 浏览:

除夕当天,微信用户发送红包总量达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.货币波动幅度很大

当初创建红包的时候,就定下了分配计划。抢红包的时候,只是一个个弹出来。

所以python代码如下:

Defweixin _ divide _ hongbao (money,n) : divide _ table=[random。xrange (0,n)中x的randint (1,10000)sum _=sum(divide _ table)返回[x * money/sum _ for x in divide。

1.浮点数精度问题

2.边界值的处理

第三个学生根据网上流传的python写了一个java版本

int j=1;while(j 1000){ int number=10;float total=100浮动货币;双最小值=0.01;双倍最大值;int I=1;list math=new ArrayList();while(in 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;总额=总额-金钱;math.add(钱);system . out . println(‘第一个‘我’的人得到‘钱’并留下‘总数’);我;if(I==number){ math . add(total);system . out . println(' I '第一个人得到' total '并留下0);}} System.out.println ('Math。(集合)的索引。max(数学))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;浮动总数=100;浮动货币;双最小值=0.01;双倍最大值;int I=1;list math=new ArrayList();while(in 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;总额=总额-金钱;math.add(钱);system . out . println(‘第一个‘我’的人得到‘钱’并留下‘总数’);我;if(I==number){ math . add(total);system . out . println(' I '第一个人得到' total '并留下0);}} System.out.println ('Math。(集合)的索引。max(数学))1)‘个人运气最好’;j;}输入吧,波动太大,数据太枯燥!

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

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

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

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

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

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

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

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

为了改善这种情况,采用平均值作为随机安全的上限来控制波动差

int j=1;while(j 1000){ int number=10;浮动总数=100;浮动货币;双最小值=0.01;双倍最大值;int I=1;list math=new ArrayList();while(in 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;总额=总额-金钱;math.add(钱);system . out . println(‘第一个‘我’的人得到‘钱’并留下‘总数’);我;if(I==number){ math . add(total);system . out . println(' I '第一个人得到' total '并留下0);}} System.out.println ('Math。(集合)的索引。max(数学))1)‘个人运气最好’;j;}输出结果见下图

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

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

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

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

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

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

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

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

总结:

边肖认为这可以理解为红包引发的血案。边肖只列举了几个,还有一些工科学生直接抛出数学模型、离散函数之类的,但不管算法是简单还是复杂,都是足够好玩的。

版权声明:大家都在抢红包 程序员都在研究红包算法是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。