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

除夕全天微信用户红包总发送量达到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 元

小结:

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

(0)

相关推荐

  • Android实现QQ抢红包插件

    又想到快要过年了,到时候还不知道群里要发好多红包,所以我将之前在网上宕的一份微信抢红包的代码修改了一下,实现了QQ抢红包!可以支持抢QQ拼手气红包,普通红包,口令红包,现在再也不怕20年单身手速的人跟我抢红包了! 先看测试效果图: 1.抢QQ口令红包  可以看见,只要红包一发出,自动填写口令并发出,帮你将红包抢到手! 2.抢QQ拼手气红包 拼手气红包也是一样,只要红包一发出,自动帮你把红包抢到手,是不是很爽的感觉? 3.抢QQ好友发送的红包 只要好友或者群里的人把红包一发出,就会第一时间让你抢到

  • 微信抢红包ASP.NET代码轻松实现

    群里都在玩抢红包,抢了再发,发了再抢,简直是无聊,程序员感兴趣是的如何实现,这里简单说说实现思路,附上dome,代码有点low,好在是实现了,具体内容如下 正文 100块发30个红包 50块发13个红包 1块发10个红包 发红包需要满足以下几个条件 1.总金额不变 2.每个红包都必须有钱 3.尽量的均匀点,不然抢红包没什么意思了 实现思路 1.首先要确定最小单位,这里是精确到分,我这里以int类型进行计算,得出的结果也全是int类型 2.数据均匀,这里以  1<n<(剩余金额/剩余红包数)*2

  • Android抢红包助手开发全攻略

    背景:新年之际,微信微博支付宝红包是到处飞,但是,自己的手速总是比别人慢一点最后导致红包没抢到,红包助手就应运而生. 需求:收到红包的时候进行提醒,然后跳转到红包的界面方便用户. 思路:获取"读取通知信息"权限,然后开启服务监控系统通知,判断如果是微信红包就进行提醒(声音),然后跳转到红包所在的地方.  界面: 界面分为两部分,一部分是可以对App进行操作的,下面是一个可以滑动的界面,提示用户如何是软件正常工作,布局代码如下: <?xml version="1.0&qu

  • Android中微信抢红包插件原理解析及开发思路

    一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导致了.或许是网络的原因,而且这个也是最大的原因.但是其他的不可忽略的因素也是要考虑到进去的,比如在手机充电锁屏的时候,我们并不知道有人已经开始发红包了,那么这时候也是让我们丧失了一大批红包的原因.那么关于网络的问题,我们开发者可能用相关技术无法解决(当然在Google和Facebook看来的话,他们

  • 教你一步步实现Android微信自动抢红包

    本文介绍微信自动抢红包的实现方法,主要实现以下几个功能: 1.自动拆开屏幕上出现的红包 2.处于桌面或聊天列表时接收到红包信息时自动进入聊天界面并拆红包 3.日志功能,记录抢红包的详细日志 实现原理 1.利用AccessibilityService辅助服务,监测屏幕内容,实现自动拆红包的目的. 2.利用ActiveAndroid数据库简单记录红包日志 3.利用preference实现监控选项纪录 最终界面 抢红包核心代码 AccessibilityService配置 android:access

  • Android实现微信自动抢红包的程序

    简单实现了微信自动抢红包的服务,原理就是根据关键字找到相应的View, 然后自动点击.主要是用到AccessibilityService这个辅助服务,基本可以满足自动抢红包的功能,但是有些逻辑需要优化,比如,拆完一个红包后,必须手动点击返回键,才能进行下一次自动抢红包. AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="h

  • Android辅助功能AccessibilityService与抢红包辅助

    推荐阅读:Android中微信抢红包插件原理解析及开发思路 抢红包的原理都差不多,一般是用Android的辅助功能(AccessibilityService类)先监听通知栏事件或窗口变化事件来查找红包关键字然后去模拟点击或打开红包. 下面附上源码,程序已实现自动抢红包,锁屏黑屏状态自动解锁亮屏,Android4.X测试通过.函数具体功能请看详细注释. 注:在聊天界面收到红包不会自动打开,因为通知栏没有消息提示从而监听不了,此时只需手动点一下即可.其他未知情况请自行用LogCat调试,源码已经有相

  • Android抢红包插件实现原理浅析

    抢红包,先看效果图~ 实现自动抢红包,解决问题有两点: 一:如何实时监听发红包的事件 二:如何在红包到来的时候自动进入页面并自动点击红包 一.如何获取红包到来的事件 为了获取红包到来状态栏的变化,我们要用到一个类:Accessibility 许多Android使用者因为各种情况导致他们要以不同的方式与手机交互. 这包括了有些用户由于视力上,身体上,年龄上的问题致使他们不能看完整的屏幕或者使用触屏,也包括了无法很好接收到语音信息和提示的听力能力比较弱的用户. Android提供了Accessibi

  • WinForm天猫双11自动抢红包源码分享

    本文实例为大家分享了抢红包源码,供大家参考,具体内容如下 1. 正确获取红包流程 2. 软件介绍 2.1 效果图: 2.2 功能介绍 2.2.1 账号登录 页面开始时,会载入这个网站:https://login.taobao.com/member/login.jhtml?redirect_url=http%3A%2F%2F1111.tmall.com%2F 登录成功后,会自动跳转到1111.tmall.com活动页面. 2.2.2 [去抽奖]按钮 这按钮是手动跳转到1111.tmall.com页

  • PHP版微信公众平台红包API

    重写了一下PHP下面的微信API接口, 微信红包支持,JSAPI的动态参数接口支持 http://git.oschina.net/youkuiyuan/yky_test/blob/master/class/wxapi.class.php 微信API类 - 增加红包支持 <?php /******************************************************** * @author Kyler You <QQ:2444756311> * @link htt

随机推荐