大家在抢红包,程序员在研究红包算法_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 元

小结:

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索微信红包
微信红包代码
抢红包算法、微信抢红包算法、java抢红包算法、微信抢红包算法 java、微信抢红包随机算法,以便于您获取更多的相关知识。

时间: 2024-09-26 22:47:41

大家在抢红包,程序员在研究红包算法_php实例的相关文章

中高级PHP程序员应该掌握哪些技术?_php实例

本文把php程序员划分为中.高级程序员两大类程序员,并针对这两大程序员应具备的技能进行分类探索. 中级PHP程序员  1.Linux  能够流畅的使用Shell脚本来完成很多自动化的工作:awk/sed/perl 也操作的不错,能够完成很多文本处理和数据统计等工作:基本能够安装大 部分非特殊的Linux程序(包括各种库.包.第三方依赖等等,比如MongoDB/Redis/Sphinx/Luncene/SVN之类的):了解基 本的Linux服务,知道如何查看Linux的性能指标数据,知道基本的Li

PHP程序员的技术成长规划_php文摘

按照了解的很多PHP/LNMP程序员的发展轨迹,结合个人经验体会,抽象出很多程序员对未来的迷漫,特别对技术学习的盲目和慌乱,简单梳理了这个每个阶段PHP程序员的技术要求,来帮助很多PHP程序做对照设定学习成长目标. 本文按照目前主流技术做了一个基本的梳理,整个是假设PHP程序员不是基础非常扎实的情况进行的设定,并且所有设定都非常具体明确清晰,可能会让人觉得不适,请理解仅代表一家之言.(未来技术变化不在讨论范围) 第一阶段:基础阶段(基础PHP程序员) 重点:把LNMP搞熟练(核心是安装配置基本操

PHP 程序员的调试技术小结_php技巧

本文介绍调试 PHP 应用程序的各种方法,包括在 Apache and PHP 中打开错误报告,以及通过在一个简单的 PHP 脚本中放置策略性的 print 语句,找到更困难的 bug 的源头.还会介绍用于 Eclipse 的 PHPEclipse 插件,这是一个灵活的开发环境,具有实时语法解析能力,还会介绍 PHPEclipse 的 DBG 调试器扩展. 简介 有许多 PHP 调试技术可以在编码的时候节约大量时间.一个有效却很基本的调试技术就是打开错误报告.另一个略微高级一点的技术包括使用 p

8个PHP程序员常用的功能汇总_php技巧

做过PHP开发的程序员应该清楚,PHP中有很多内置的功能,掌握了它们,可以帮助你在做PHP开发时更加得心应手,本文将分享8个开发必备的PHP功能,个个都非常实用,希望各位PHP开发者能够掌握. 1.传递任意数量的函数参数 我们在.NET或者JAVA编程中,一般函数参数个数都是固定的,但是PHP允许你使用任意个数的参数.下面这个示例向你展示了PHP函数的默认参数: 复制代码 代码如下: // 两个默认参数的函数 function foo($arg1 = ", $arg2 = ") { e

如何突破PHP程序员的技术瓶颈分析_php文摘

先明确我所指的PHP工程题,是指毕业工作后,主要以PHP进行WEB系统的开发,没有使用其的语言工作过.工作经验大概在3~4年,普通的WEB系统(百万级访问,千成级数据以内或业务逻辑不是特别复杂)开发起基本得心应手,没有什么问题.但他们会这样的物点: 除了PHP不使用其它的语言,可能会点shell 脚本. 对PHP的掌握不精(很多PHP手册都没有看完,库除外) 知识面比较窄(面对需求,除开使用PHP和mysql ,不知道其它的解决办法) PHP代码以过程为主,认为面向对象的实现太绕,看不懂 这些P

java 微信随机红包算法代码实例_java

前几天的一个晚上突然想到微信红包应该有一个随机算法,就自己试着写了下,也不知道对不对,看了看网上的说法,好像到现在为止官方也没有给出一个确切的算法,只好在这里献丑了,先贴出代码: public static double [] getMoney(double money, int num){ Random r = new Random(); DecimalFormat format = new DecimalFormat(".##"); double middle = Double.p

PHP仿微信发红包领红包效果_php实例

近期项目需要在聊天的基础上新增红包功能,需求:仿微信(不含留言),但只能使用余额发红包.于是多次使用微信红包,了解各种交互界面及业务需求,如展示信息.分类(个人,群普通,群拼手气).个数限制(100).金额限制(200).过期时间(24小时)等等,然后着手开发,下面提及的基本全是提供给app端的接口,毕竟我是phper. 一.设计数据表如下 CREATE TABLE `red_packet` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `us

PHP实现采集程序原理和简单示例代码_php实例

<entry SKIPIFREF="YES">  <title>I Believe In Love</title>  <author> 蓝牙音乐网 - 8391.com</author>  <copyright> 蓝牙音乐网 - 8391.com</copyright>  <ref href="http://218.78.213.183:880/daolianmtvfuc________

PHP图形计数器程序显示网站用户浏览量_php实例

PHP图形计数器程序是一款简单的图片计数器,为了直观显示一个网站有多少用户浏览,需要在网页底部放一个图片计数器,也就是当前页面的访问量,访问量的数据是保存在 txt 文件里,可自动生成 num.txt 文件,自定义初始数据,显示的数字图片保存在 img 目录下,可以换成自己做的精美的图片,更换即可,index.php是调用文件,很简单. 本程序只有几十KB,系统代码设计简单易懂. 效果如下: 关于程序的安装很简单: 1.这款图形计数器不需要数据库的支持,只要能运行PHP即可,将index.php