java版本:java
/** * Created by liuyaowen on 2016/8/3. */ import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; /** * JAVA 返回隨機數,並根據機率、比率 * */ public class MathRandom { /** * 根據Math.random()產生一個double型的隨機數,判斷每一個獎品出現的機率 * @param prizes * @return random:獎品列表prizes中的序列(prizes中的第random個就是抽中的獎品) */ public int getPrizeIndex(List<Prize> prizes) { int random = -1; try{ //計算總權重 double sumWeight = 0; for(Prize p : prizes){ sumWeight += p.getPrize_weight(); } //產生隨機數 double randomNumber; randomNumber = Math.random(); System.out.println("隨機誰:"+randomNumber); //根據隨機數在全部獎品分佈的區域並肯定所抽獎品 double d1 = 0; double d2 = 0; for(int i=0;i<prizes.size();i++){ if(i==0){ d1 = 0; }else{ d1=d2; } d2 += Double.parseDouble(String.valueOf(prizes.get(i).getPrize_weight()))/sumWeight; if(randomNumber >= d1 && randomNumber <= d2){ random = i; break; } } }catch(Exception e){ System.out.println("生成抽獎隨機數出錯,出錯緣由:" +e.getMessage()); } return random; } /** * 測試主程序 * * @param agrs */ public static void main(String[] agrs) { System.out.println("8%(2<<3)==="+8%(2<<3)); int i = 0; MathRandom a = new MathRandom(); int[] result=new int[4]; List<Prize> prizes = new ArrayList<Prize>(); Prize p1 = new Prize(); p1.setPrize_name("范冰冰海報"); p1.setPrize_weight(4);//獎品的權重設置成1 prizes.add(p1); Prize p2 = new Prize(); p2.setPrize_name("上海紫園1號別墅"); p2.setPrize_weight(1);//獎品的權重設置成2 prizes.add(p2); Prize p3 = new Prize(); p3.setPrize_name("奧迪a9"); p3.setPrize_weight(3);//獎品的權重設置成3 prizes.add(p3); Prize p4 = new Prize(); p4.setPrize_name("雙色球彩票"); p4.setPrize_weight(2);//獎品的權重設置成4 prizes.add(p4); System.out.println("抽獎開始"); for (i = 0; i < 10000; i++)// 打印100個測試機率的準確性 { int selected=a.getPrizeIndex(prizes); System.out.println("第"+i+"次抽中的獎品爲:"+prizes.get(selected).getPrize_name()); result[selected]++; System.out.println("--------------------------------"); } System.out.println("抽獎結束"); System.out.println("每種獎品抽到的數量爲:"); System.out.println("一等獎:"+result[0]); System.out.println("二等獎:"+result[1]); System.out.println("三等獎:"+result[2]); System.out.println("四等獎:"+result[3]); } } class Prize{ private int id;//獎品id private String prize_name;//獎品名稱 private int prize_amount;//獎品(剩餘)數量 private int prize_weight;//獎品權重 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPrize_name() { return prize_name; } public void setPrize_name(String prize_name) { this.prize_name = prize_name; } public int getPrize_amount() { return prize_amount; } public void setPrize_amount(int prize_amount) { this.prize_amount = prize_amount; } public int getPrize_weight() { return prize_weight; } public void setPrize_weight(int prize_weight) { this.prize_weight = prize_weight; } }
oracle版:sql
function FN_LOAD_PRIZE(P_ACTIVITYID varchar2, --活動名字 P_GROUP varchar2 --新老用戶區分 ) return Number is v_sumWeight number(4,2);--總的權重 --根據隨機數在全部獎品分佈的區域並肯定所抽獎品 v_d1 number(18,10); v_d2 number(18,10); v_random number(18,10);--隨機數 v_index number;--循環中的下標 v_prize number; --獎品列表prizes中的序列(prizes中的第random個就是抽中的獎品) --獎品池 cursor cur_prizeinfo is select * from fsapi.tprizeinfo t where t.pgroup='old' and t.activityno='8A0D108DCEE640D98351791D672C500E'; prizeinfo cur_prizeinfo%rowtype; begin v_d2 :=0; v_index :=0; --1.計算總的權重 select sum(t.pweight) into v_sumWeight from fsapi.tprizeinfo t where t.pgroup='old' and t.activityno='8A0D108DCEE640D98351791D672C500E'; --2.生產隨機數 select dbms_random.value into v_random from dual ; dbms_output.put_line('活動NO:'||P_ACTIVITYID||',分組:'||P_GROUP||'總的權重:'||v_sumWeight||'隨機數:'||v_random); --3.循環獎品池 open cur_prizeinfo;--打開遊標 loop fetch cur_prizeinfo into prizeinfo; exit when cur_prizeinfo%notfound; --dbms_output.put_line('獎品名字'||prizeinfo.pname||',分組:'||prizeinfo.pgroup||'總的權重:'||prizeinfo.pweight); if (v_index = 0) then v_d1 := 0; else v_d1 := v_d2; end if; v_d2 := v_d2+(prizeinfo.pweight / v_sumWeight); dbms_output.put_line('v_d1:'||v_d1||',v_d2:'||v_d2||'v_random:'||v_random||'pweight:'||prizeinfo.pweight); --計算區段是否在獎品中。 if(randomNumber >= d1 && randomNumber <= d2){ if (v_random >= v_d1 and v_random <= v_d2 and prizeinfo.povercount>0) then v_prize := prizeinfo.pid;--返回獎品ID --更新獎品數量 update fsapi.tprizeinfo t set t.povercount=t.povercount-1 where t.pid=prizeinfo.pid; commit; exit; end if; v_index := v_index+1; end loop; close cur_prizeinfo; return v_prize; end;