生活随笔
收集整理的這篇文章主要介紹了
抢红包的红包生成算法
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
過年微信紅包很火,最近有個項目也要做搶紅包,于是寫了個紅包的生成算法。
紅包生成算法的需求
預(yù)先生成所有的紅包還是一個請求隨機生成一個紅包
簡單來說,就是把一個大整數(shù)m分解(直接以“分為單位,如1元即100)分解成n個小整數(shù)的過程,小整數(shù)的范圍是[min, max]。
最簡單的思路,先保底,每個小紅包保證有min,然后每個請求都隨機生成一個0到(max-min)范圍的整數(shù),再加上min就是紅包的錢數(shù)。
這個算法雖然簡單,但是有一個弊端:最后生成的紅包可能都是min錢數(shù)的。也就是說可能最后的紅包都是0.01元的。
另一種方式是預(yù)先生成所有紅包,這樣就比較容易控制了。我選擇的是預(yù)先生成所有的紅包。
理想的紅包生成算法
理想的紅包生成結(jié)果是平均值附近的紅包比較多,大紅包和小紅包的數(shù)量比較少。
可以想像下,生成紅包的數(shù)量的分布有點像正態(tài)分布。
那么如何實現(xiàn)這種平均線附近值比較多的要求呢?
就是要找到一種算法,可以提高平均值附近的概率。那么利用一種”膨脹“再”收縮“的方式來達(dá)到這種效果。
先平方,再生成平方范圍內(nèi)的隨機數(shù),再開方,那么概率就不再是平均的了。
具體算法:
[java]?view plaincopy
public?class?HongBaoAlgorithm?{?? ????static?Random?random?=?new?Random();?? ????static?{?? ????????random.setSeed(System.currentTimeMillis());?? ????}?? ?????? ????public?static?void?main(String[]?args)?{?? ????????long?max?=?200;?? ????????long?min?=?1;?? ?? ????????long[]?result?=?HongBaoAlgorithm.generate(100_0000,?10_000,?max,?min);?? ????????long?total?=?0;?? ????????for?(int?i?=?0;?i?<?result.length;?i++)?{?? ?????????????? ?????????????? ????????????total?+=?result[i];?? ????????}?? ?????????? ????????System.out.println("total:"?+?total);?? ?? ?????????? ????????int?count[]?=?new?int[(int)?max?+?1];?? ????????for?(int?i?=?0;?i?<?result.length;?i++)?{?? ????????????count[(int)?result[i]]?+=?1;?? ????????}?? ?? ????????for?(int?i?=?0;?i?<?count.length;?i++)?{?? ????????????System.out.println(""?+?i?+?"??"?+?count[i]);?? ????????}?? ????}?? ?????? ????? ? ? ? ? ? ? ?? ????static?long?xRandom(long?min,?long?max)?{?? ????????return?sqrt(nextLong(sqr(max?-?min)));?? ????}?? ?? ????? ? ? ? ? ? ? ? ? ? ? ?? ????public?static?long[]?generate(long?total,?int?count,?long?max,?long?min)?{?? ????????long[]?result?=?new?long[count];?? ?? ????????long?average?=?total?/?count;?? ?? ????????long?a?=?average?-?min;?? ????????long?b?=?max?-?min;?? ?? ?????????? ?????????? ?????????? ????????long?range1?=?sqr(average?-?min);?? ????????long?range2?=?sqr(max?-?average);?? ?? ????????for?(int?i?=?0;?i?<?result.length;?i++)?{?? ?????????????? ?????????????? ?????????????? ????????????if?(nextLong(min,?max)?>?average)?{?? ?????????????????? ?? ????????????????long?temp?=?min?+?xRandom(min,?average);?? ????????????????result[i]?=?temp;?? ????????????????total?-=?temp;?? ????????????}?else?{?? ?????????????????? ?? ????????????????long?temp?=?max?-?xRandom(average,?max);?? ????????????????result[i]?=?temp;?? ????????????????total?-=?temp;?? ????????????}?? ????????}?? ?????????? ????????while?(total?>?0)?{?? ????????????for?(int?i?=?0;?i?<?result.length;?i++)?{?? ????????????????if?(total?>?0?&&?result[i]?<?max)?{?? ????????????????????result[i]++;?? ????????????????????total--;?? ????????????????}?? ????????????}?? ????????}?? ?????????? ????????while?(total?<?0)?{?? ????????????for?(int?i?=?0;?i?<?result.length;?i++)?{?? ????????????????if?(total?<?0?&&?result[i]?>?min)?{?? ????????????????????result[i]--;?? ????????????????????total++;?? ????????????????}?? ????????????}?? ????????}?? ????????return?result;?? ????}?? ?? ????static?long?sqrt(long?n)?{?? ?????????? ????????return?(long)?Math.sqrt(n);?? ????}?? ?? ????static?long?sqr(long?n)?{?? ?????????? ????????return?n?*?n;?? ????}?? ?????? ????static?long?nextLong(long?n)?{?? ????????return?random.nextInt((int)?n);?? ????}?? ?? ????static?long?nextLong(long?min,?long?max)?{?? ????????return?random.nextInt((int)?(max?-?min?+?1))?+?min;?? ????}?? }??
統(tǒng)計了下生成的結(jié)果,還是比較符合要求的。
總結(jié)
以上是生活随笔為你收集整理的抢红包的红包生成算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。