微信紅包演算法-隨機加權演算法
微信紅包演算法-隨機加權演算法
最近突然對微信紅包的演算法非常感興趣,就按照自己的想法寫了一個演算法,原理是根據隨機加權數演算法,演算法中就按照微信的校驗規則給出。
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個數據樣本曲線:
部分樣本資料: