Home  >  Article  >  Backend Development  >  Discussion on Algorithm Implementation of WeChat Red Envelopes (Based on PHP)

Discussion on Algorithm Implementation of WeChat Red Envelopes (Based on PHP)

伊谢尔伦
伊谢尔伦Original
2016-11-26 17:10:451097browse

Tonight, I had a sudden idea and sent a red envelope to the alumni WeChat group. I set the total amount of the red envelope to 10 yuan, allowing 28 people to receive it randomly.

So an interesting result appeared:

A received 0.26 yuan
B received 0.29 yuan
C received 0.02 yuan
D received 0.56 yuan
E received 0.64 yuan
...

What does WeChat use? What kind of algorithm does it do? I simply checked on Baidu and found that there is no official explanation yet. There is only a relatively popular discussion in Zhihu. Click here for the link. However, their discussion is too in-depth and seems to be a trap.

I tried it according to my own logic. This algorithm needs to meet the following requirements:

1. Everyone must be able to receive the red envelope;

2. The sum of the red envelope amount received by each person = the total amount;

3. The amount of red envelopes received by each person varies, but the difference cannot be too outrageous, otherwise it will be uninteresting;

4. The algorithm must be simple, otherwise it will fail Tencent’s signature;

Before formal coding, build one first Progressive model to analyze the pattern

Set the total amount to 10 yuan, and N people randomly receive it:

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 
……

At this point, the pattern appears! Start coding!

header("Content-Type: text/html;charset=utf-8");//输出不乱码,你懂的
$total=10;//红包总额
$num=8;// 分成8个红包,支持8人随机领取
$min=0.01;//每个人最少能收到0.01元
for ($i=1;$i<$num;$i++)
{
    $safe_total=$total-($num-$i)*$min;//随机安全上限
    $money=mt_rand($min*100,$safe_total*100)/100;
    $total=$total-$money;
    echo &#39;第&#39;.$i.&#39;个红包:&#39;.$money.&#39; 元,余额:&#39;.$total.&#39; 元 <br/>&#39;;
}
echo &#39;第&#39;.$num.&#39;个红包:&#39;.$total.&#39; 元,余额:0 元&#39;;

After inputting it, the fluctuation is too big and the data is too boring!

第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 元

Improve it and use the average value as the random safety upper limit to control the fluctuation difference

header("Content-Type: text/html;charset=utf-8");//输出不乱码,你懂的
$total=10;//红包总额
$num=8;// 分成8个红包,支持8人随机领取
$min=0.01;//每个人最少能收到0.01元
for ($i=1;$i<$num;$i++)
{
    $safe_total=($total-($num-$i)*$min)/($num-$i);//随机安全上限
    $money=mt_rand($min*100,$safe_total*100)/100;
    $total=$total-$money;
    echo &#39;第&#39;.$i.&#39;个红包:&#39;.$money.&#39; 元,余额:&#39;.$total.&#39; 元 <br/>&#39;;
}
echo &#39;第&#39;.$num.&#39;个红包:&#39;.$total.&#39; 元,余额:0 元&#39;;

The output results are shown in the figure below

第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