RedPaket - 微信紅包金額分配算法

紅包領了不少,據觀察紅包主要有以下幾個限制條件:

  • 1.所有人都能分到紅包,也就是不會出現紅包數值為0的情況。
  • 2.所有人的紅包數值加起來等于支付的金額。
  • 3.紅包波動范圍比較大,約5%~8%的紅包數值在平均值的兩倍以上,同時數額0.01出現的概率比較高。
  • 4.紅包的數值是隨機的,并且數值的分布近似于正態分布。

基本思路:

  • 1.因為要保證每個人都至少搶到一分錢,那么首先給每個人分配1分錢
  • 2.剩下的錢再隨機分給每個人,Ruby的隨機函數是平均分布的,因此如果需要使紅包金額近似正態分布,需要對平均分布進行Box–Muller轉換操作
  • 3.由于精度問題,最后一個紅包需要用總的紅包金額-已分配的金額
  • 4.得到服從正態分布的隨機數的基本思想是先得到服從均勻分布的隨機數,再將服從均勻分布的隨機數轉變為服從正態分布

Box-Muller

Box-Muller是產生隨機數的一種方法。Box-Muller算法隱含的原理非常深奧,但結果卻是相當簡單。如果在(0,1]值域內有兩個一致的隨機數字U1和U2,可以使用以下兩個等式中的任一個算出一個正態分布的隨機數字Z:

  • Z=Rcos(θ)或Z=Rsin(θ)
  • 其中,R=sqrt(-2ln(U2));θ=2π*U1
  • 正態值Z有一個等于0的平均值和一個等于1的標準偏差,可使用以下等式將Z映射到一個平均值為m、標準偏差為sd的統計量X:
  • X=m+(Z*sd)
  • </ul>

    測試:

    generateMoneyVector(1, 3)
    [0.42, 0.38, 0.2]
    [0.49, 0.06, 0.45]
    [0.18, 0.54, 0.28]

    generateMoneyVector(1, 10) [0.13, 0.11, 0.08, 0.13, 0.01, 0.11, 0.04, 0.15, 0.16, 0.08] [0.07, 0.12, 0.11, 0.15, 0.08, 0.05, 0.14, 0.18, 0.03, 0.07] [0.12, 0.08, 0.15, 0.10, 0.11, 0.04, 0.04, 0.10, 0.05, 0.21]</pre> </div>

    項目地址: https://github.com/MichaelRoshen/RedPaket

     本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!