標籤:
根據權重進行抽取的演算法應用比較廣泛,其中抽獎便是主要用途之一。正好這幾天也進行中抽獎模組的開發,整個抽獎模組涉及到的地方大概有三處,分別是後台進行獎品的添加(同時設定權重和數量),前台根據後台配置產生抽獎隊列並根據指令開始抽獎活動,最後一部分是後台統計中獎情況並設定物流狀態。本文主要針對前台抽獎演算法進行介紹如何根據權重設定每個獎品被抽到的機率。
抽獎演算法的核心是根據權重設定隨機數出現的機率,在此我將它封裝成一個產生隨機數的隨機類,代碼如下:
/** * JAVA 返回隨機數,並根據機率、比率 * */public class MathRandom {private static Log logger = LogFactory.getLog(MathRandom.class);/** * Math.random()產生一個double型的隨機數,判斷一下 每個獎品出現的機率 * * @return int * */public int PercentageRandom(List<RewardPrize> prizes) {DecimalFormat df = new DecimalFormat("######0.00"); int random = -2;try{double sumWeight = 0;//計算總權重for(RewardPrize rp_1 : prizes){sumWeight += rp_1.getPrize_weight();}double randomNumber;randomNumber = Math.random();System.out.println("randomNumber是:" + randomNumber);double d1 = 0;double d2 = 0;for(int i=0;i<prizes.size();i++){d2 += Double.parseDouble(String.valueOf(prizes.get(i).getPrize_weight()))/sumWeight;if(i==0){d1 = 0;}else{d1 +=Double.parseDouble(String.valueOf(prizes.get(i-1).getPrize_weight()))/sumWeight;}if(randomNumber >= d1 && randomNumber <= d2){random = i;System.out.println("d1是:" + d1);System.out.println("d2是:" + d2);break;}}}catch(Exception e){System.out.println(e.getMessage());logger.error("產生抽獎隨機數出錯,出錯原因:" + e.getMessage());random = -1;}return random;}/** * 測試主程式 * * @param agrs */public static void main(String[] agrs) {int i = 0;MathRandom a = new MathRandom();List<RewardPrize> prizes = new ArrayList();for(int m=0;m<100;m++){RewardPrize rp = new RewardPrize();rp.setPrize_amount(10);//每個獎品數量設定10個rp.setPrize_weight(1);//每個獎品的權重都設定成1,也就是每個獎品被抽到的機率相同(可根據情況自行設定權重)prizes.add(rp);}for (i = 0; i <= 100; i++)// 列印100個測試機率的準確性{System.out.println(a.PercentageRandom(prizes));}}}
簡單介紹一下上面的代碼含義,首先計算出待選獎品的總權重,這樣做的目的是可以隨意設定獎品權重,不必再考慮權重之和是否等於100。隨機規則是首先產生一個隨機數randomNumber(產生的隨機數位於0到1的左開右閉區間),然後分別計算出當前獎品前前面所有有獎品(不包括當前獎品)的機率和d1和當前獎品後面(包括當前獎品)所有獎品的機率和d2,然後判斷產生的隨機數randomNumber是否已處於d1和d2之間,如果處於該區間之內則當前獎品將被抽中。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
java版根據權重抽獎演算法