參考:
進入知乎《微信紅包的隨機算法是怎樣實現的》查看更多人的算法。
最近看到搶紅包這么火,早就想嘗試去把搶紅包的功能試着去做一做了。剛好今天看到參考的網址,就產生了這一篇總結性的文章了。
我的早期邏輯猜想?
- 發紅包者在發紅包的時候,內存中存放的是紅包的總額和紅包的個數。然后在用戶點擊“拆紅包”的時候,向服務器接口請求,服務器邏輯給用戶計算出一個隨機值(紅包多少錢?),返回給前端。依次類推。
- 每次計算隨機值時,都是用剩余的錢數除剩余拆紅包的人,得出一個平均值,利用這個平均值去平衡每一個搶紅包的用戶得到的錢。
- 並沒有第三,謝謝。
不過,看完參考的文章,思路還是有一定的改進的。在每個用戶點擊”拆紅包”的時候,並沒有像我想象中的那樣去計算用戶獲得多少錢的紅包,而是在發紅包的時候(就是輸入總額和紅包個數,付款后並提交到服務器的時候),服務器就已經計算出每個紅包的額度並存放到內存中了。那么當每個用戶點擊”拆紅包”的時候,服務器直接就把”結果”(紅包的數值)給前端就完成了一次領紅包的操作了。從性能上看,這種方法明顯優於我之前的想法,但是,從存儲空間上分析,如果發的紅包個數太多的話,就會非常消耗內存了。
邏輯代碼:
1 <?php 2 3 $total_money = 1000;//發紅包的總額,單位:分 4 $num = 8;//發紅包的個數 5 $min_money = 1;//每個人至少得到多少錢? 6 7 for ($i = 1; $i <= $num; $i++) { 8 if ($i == $num) {//最后一個紅包就直接等於余額 9 $money = $total_money; 10 $total_money = 0; 11 } else { 12 //$max_money是整個算法比較重要的部分,這個數值將決定了紅包活動的公平性。 13 //這里只是比較簡單的一種方式,如果真要當功能去做的話,這里的max_money值獲取的算法肯定是要優化的。 14 $max_money = $total_money / ($num-$i);// $total_money相當於整個紅包的余額,$num-$i相當於剩下還有多少人沒有領紅包 15 $money = mt_rand($min_money, $max_money); 16 $total_money -= $money; 17 } 18 $money /= 100; 19 $tmp = $total_money / 100; 20 echo "第{$i}個紅包的數值為{$money}元, 余額為: {$tmp}元\n";
不才之見,歡迎吐槽。