1. 程式人生 > >微信紅包演算法-隨機加權演算法

微信紅包演算法-隨機加權演算法

                           微信紅包演算法-隨機加權演算法

 

最近突然對微信紅包的演算法非常感興趣,就按照自己的想法寫了一個演算法,原理是根據隨機加權數演算法,演算法中就按照微信的校驗規則給出。

 

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個數據樣本曲線:


部分樣本資料: