演算法:很簡單:
基於截尾正態分佈,數額隨機,額度在0.01和剩餘平均值*2之間。實現上述演算法的邏輯主要是:
publicredpackage資料結構如下:static
bigdecimal getrandommoney(redpackage redpackage)
random r = new
random();
bigdecimal min = new bigdecimal(0.01);
bigdecimal max = remainmoney.divide(new bigdecimal(remainsize * 2), 2, roundingmode.half_up);
bigdecimal money = max.multiply(new
bigdecimal(r.nextint()));
if (money.compareto(new bigdecimal(0.01)) < 0)
remainsize--;
remainmoney =remainmoney.subtract(money);
redpackage.setremainsize(remainsize);
redpackage.setremainmoney(remainmoney);
return
money;
}
publicclass
redpackage
public
void setremainsize(int
remainsize)
public
bigdecimal getremainmoney()
public
void
setremainmoney(bigdecimal remainmoney)
}
remainsize = 30;單次測試隨機紅包remainmoney = 500;
以上面的初始化資料(30人搶500塊),執行了兩次,結果如下:
//對應圖表如下:第一次15.69 21.18 24.11 30.85 0.74 20.85 2.96 13.43 11.12 24.87 1.86 19.62 5.97 29.33 3.05 26.94 18.69 34.47 9.4 29.83 5.17 24.67 17.09 29.96 6.77 5.79 0.34 23.89 40.44 0.92
//第二次
10.44 18.01 17.01 21.07 11.87 4.78 30.14 32.05 16.68 20.34 12.94 27.98 9.31 17.97 12.93 28.75 12.1 12.77 7.54 10.87 4.16 25.36 26.89 5.73 11.59 23.91 17.77 15.85 23.42 9.77
第一次:
第二次:
200次:
2000次:
為什麼不採用完全隨機的辦法?
這種產生機理不好的地方在於:大多數人得到的錢非常少,而極少數人得到的錢卻非常多,而這可能會對抽取人的積極性產生影響。截尾正態分佈能夠更好地避免這樣的問題,因為更多人的紅包大小會聚集在平均值附近,而且由於尾部更快的衰減,因此獲得特別大的紅包的概率也會相應減小,有助於增加公平性與參與的積極性。儘管具體截尾的範圍可能需要獲取更多的資料才有可能有乙個準確的**。
實時性:為什麼明明搶到紅包,點開後發現沒有?
2023年的紅包一點開就知道金額,分兩次操作,先搶到金額,然後再轉賬。
2023年的紅包的拆和搶是分離的,需要點兩次,因此會出現搶到紅包了,但點開後告知紅包已經被領完的狀況。進入到第乙個頁面不代表搶到,只表示當時紅包還有。
分配:紅包裡的金額怎麼算?為什麼出現各個紅包金額相差很大?
隨機,額度在0.01和(剩餘平均值*2)之間。
例如:發100塊錢,總共10個紅包,那麼平均值是10塊錢乙個,那麼發出來的紅包的額度在0.01元~20元之間波動。
當前面3個紅包總共被領了40塊錢時,剩下60塊錢,總共7個紅包,那麼這7個紅包的額度在:0.01~(60/7*2)=17.14之間。
注意:這裡的演算法是每被搶乙個後,剩下的會再次執行上面的這樣的演算法
這樣算下去,會超過最開始的全部金額,因此到了最後面如果不夠這麼算,那麼會採取如下演算法:保證剩餘使用者能拿到最低1分錢即可。
如果前面的人手氣不好,那麼後面的餘額越多,紅包額度也就越多,因此實際概率一樣的。
cache會抵抗無效請求,將無效的請求過濾掉,實際進入到後台的量不大。cache記錄紅包個數,原子操作進行個數遞減,到0表示被搶光。財付通按照20萬筆每秒入賬準備,但實際還不到8萬每秒。
多主sharding,水平擴充套件機器。
乙個紅包只佔一條記錄,有效期只有幾天,因此不需要太多空間。
搶到紅包的人數和紅包都在一條cache記錄上,沒有太大的查詢壓力。
沒有佇列,乙個紅包一條資料,資料上有乙個計數器字段。
不是絕對均等,就是乙個簡單的拍腦袋演算法。
會出現金額一樣的,但是手氣最佳只有乙個,先搶到的那個最佳。
每搶到乙個紅包,就cas更新剩餘金額和紅包個數。
資料庫會累加已經領取的個數與金額,插入一條領取記錄。入賬則是後台非同步操作。
PHP實現微信紅包演算法和微信紅包的架構設計簡介
使用php發紅包,當我們輸入紅包數量和總金額後,php會根據這兩個值進行隨機分配每個金額,保證每個人都能領取到乙個紅包,每個紅包金額不等,就是要求紅包金額要有差異,所有紅包金額總額應該等於總金額。設定總金額為10元,有n個人隨機領取 n 1 第乙個 則紅包金額 x元 n 2 第二個 為保證第二個紅包...
微信搶紅包演算法實現
只討論金額隨機的情況,需要滿足規則 所有人搶到金額之和要等於紅包總金額1.每個人至少搶到一分錢1.要保證所有人搶到金額的機率相等方案一 每個人點進來領,金額隨機,隨機的上限是當前剩餘的紅包金額。每次搶到的金額 隨機區間 0,剩餘紅包金額 分析 這樣做的缺陷是越早領越有優勢,因為每次搶到的金額 隨機區...
微信紅包生成演算法 解
echo 第 i.個紅包 money.元,餘額 total.元 echo 第 num.個紅包 total.元,餘額 0 元 set packet 10,10 前段時間看到乙個方法,是算紅包隨機生成金額 total 為使用者輸入的總金額.num 為分發總個數.min 為最少金額,一般都是 1 分錢的,...