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版:
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;