微信红包算法-随机加权算法
微信红包算法-随机加权算法
最近突然对微信红包的算法非常感兴趣,就按照自己的想法写了一个算法,原理是根据随机加权数算法,算法中就按照微信的校验规则给出。
1. 判断金额Amount (分)>红包个数N(N>=1); 并且红包金额<红包个数*200*100;
2. 创建一个一维数组,数组个数=红包个数;
3. 生成一组随机数,从1到红包金额*100(原因是增加随机性),arry(N)
4. 将随机数arry(N)求总和total,然后计算出每个随机数在总和中的权重,再乘上总金额减去每人至少抢到1分的钱(Amount-N*1),然后四舍五入进行取整,得到一个新的随机数组arry_new(N),
即arry_new(i)=round(arry(i)/sum(arry())*(Amount-N))+1
5. 当红包个数N>1的时候,随机生成一个1到N的随机数K。
6. 当数组中第K个值>=2的时候,将其他数组的值相加total,然后用总金额amount减去去除第K个值后的总total和,如果amount-total>=1即为数组的第K个值;否则如果数组中第K个值<2,或者总金额减去去除第K个值后的总和<1,重复第5,6两步;
这里解释一下最后两步的作用,原因是用于第四步得到的数据是通过四舍五入来的,极端情况下会导致生成的数据和总金额不相等,中间有一定的误差,通过该方法还平衡该误差,这个随机生成的K也是一个幸运儿,如果这里想简单,可以直接找出最大的一个来进行平衡也可以。
该说明按照小单位分来实现,如果想修改为元,只需要同步换算一下单位即可
伪代码:
If(amount>=N and amount<=200*100*N){
Arry(N)=int(rand()*amount*1000) --生成一个随机数组
For(i=1;i++;i<=N){
arry_new()=round(arry(i)/sum(arry())*(Amount-N))+1
-- arry(i)/sum(arry())这是权重
-- arry(i)/sum(arry())*(Amount-N) 这是权重占剩余部分的份额
-- +1 是为了每个人至少得到1分钱
}
flag=0 --给个标签,下面部分主要是实现上面的第5和第6步
do
k=int(rand()*N)
For(i=1;i++;i<=N){
If(i!=k){--这里排除第k个数组的值
Total=arry_new(i)+Total
}
}
If(amount- Total>=1){
--如果总的金额减去除第N个数组的金额>=1,即余额就是数组第N个值
Arry_new(k)= amount- Total
Flag=1 --这时,标签为1
}
Loop Until flag =1 --标签为1的时候结束上面的循序。
}.
下面是通过VB编程得出的数据:
10000个数据样本曲线:
部分样本数据: