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(Listprizes) { 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 = 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 prizes = new ArrayList (); 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版:
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;