一、简单介绍
如有4个元素A、B、C、D,权重分别为1、2、3、4,随机结果中A:B:C:D的比例要为1:2:3:4。
总体思路:累加每个元素的权重A(1)-B(3)-C(6)-D(10),则4个元素的的权重管辖区间分别为[0,1)、[1,3)、[3,6)、[6,10)。然后随机出一个[0,10)之间的随机数。
落在哪个区间,则该区间之后的元素即为按权重命中的元素。
二、核心代码
public static String getWeight(List<WeightCategory> categorys) {
Integer weightSum = 0;
String result=null;
for (WeightCategory wc : categorys) {
weightSum += wc.getWeight();
}
if (weightSum <= 0) {
System.err.println("Error: weightSum=" + weightSum.toString());
return result;
}
Random random = new Random();
Integer n = random.nextInt(weightSum); // n in [0, weightSum)
Integer m = 0;
for (WeightCategory wc : categorys) {
if (m <= n && n < m + wc.getWeight()) {
result=wc.getCategory();
break;
}
m += wc.getWeight();
}
return result;
}
三、完整实例
public class WeightTest {
public static void main(String[] args){
//测试数据
List<WeightCategory> categoryList=new ArrayList<>();
WeightCategory weightCategory1=new WeightCategory("一等奖",10);
WeightCategory weightCategory2=new WeightCategory("二等奖",20);
WeightCategory weightCategory3=new WeightCategory("三等奖",30);
WeightCategory weightCategory4=new WeightCategory("四等奖",40);
categoryList.add(weightCategory1);
categoryList.add(weightCategory2);
categoryList.add(weightCategory3);
categoryList.add(weightCategory4);
String result="";
int a1=0,a2=0,a3=0,a4=0;
for (int i=0;i<100;i++){
result = getWeight(categoryList);
System.out.println(i+" 开奖结果: "+result);
if(result.equals("一等奖")){
a1++;
}
else if(result.equals("二等奖")){
a2++;
}
else if(result.equals("三等奖")){
a3++;
}
else if(result.equals("四等奖")){
a4++;
}
}
System.out.println("一等奖共出现 "+a1);
System.out.println("二等奖共出现 "+a2);
System.out.println("三等奖共出现 "+a3);
System.out.println("四等奖共出现 "+a4);
}
/**
* 权重获取方法
* @param categorys
* @return
*/
public static String getWeight(List<WeightCategory> categorys) {
Integer weightSum = 0;
String result=null;
for (WeightCategory wc : categorys) {
weightSum += wc.getWeight();
}
if (weightSum <= 0) {
System.err.println("Error: weightSum=" + weightSum.toString());
return result;
}
Random random = new Random();
Integer n = random.nextInt(weightSum); // n in [0, weightSum)
Integer m = 0;
for (WeightCategory wc : categorys) {
if (m <= n && n < m + wc.getWeight()) {
result=wc.getCategory();
break;
}
m += wc.getWeight();
}
return result;
}
}
class WeightCategory{
private String category;//类别
private int weight;//权重值
public WeightCategory(String category, int weight) {
this.category = category;
this.weight = weight;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
四、改进版
现在对每个奖项设置数量限制:
第一步,改进WeightCategory实体
private String category;//类别
private int weight;//权重值
private int maxNum;//最大出现次数
第二步,修改main方法进行测试
public static void main(String[] args){
List<WeightCategory> categoryList=new ArrayList<>();
WeightCategory weightCategory1=new WeightCategory("一等奖",10,10);
WeightCategory weightCategory2=new WeightCategory("二等奖",20,20);
WeightCategory weightCategory3=new WeightCategory("三等奖",30,30);
WeightCategory weightCategory4=new WeightCategory("四等奖",40,40);
categoryList.add(weightCategory1);
categoryList.add(weightCategory2);
categoryList.add(weightCategory3);
categoryList.add(weightCategory4);
String result="";
int a1=0,a2=0,a3=0,a4=0;
//抽奖次数120次,观察结果
for (int i=0;i<120;i++){
result = getWeight(categoryList);
System.out.println(i+" 开奖结果: "+result);
if(result.equals("一等奖")){
a1++;
weightCategory1.setMaxNum(weightCategory1.getMaxNum()-1);
}
else if(result.equals("二等奖")){
a2++;
weightCategory2.setMaxNum(weightCategory2.getMaxNum()-1);
}
else if(result.equals("三等奖")){
a3++;
weightCategory3.setMaxNum(weightCategory3.getMaxNum()-1);
}
else if(result.equals("四等奖")){
a4++;
weightCategory4.setMaxNum(weightCategory4.getMaxNum()-1);
}
if(weightCategory1.getMaxNum()==0){
System.out.println("一等奖抽奖结束");
weightCategory1.setMaxNum(-1);
categoryList.remove(weightCategory1);
}
if(weightCategory2.getMaxNum()==0){
System.out.println("二等奖抽奖结束");
weightCategory2.setMaxNum(-1);
categoryList.remove(weightCategory2);
}
if(weightCategory3.getMaxNum()==0){
System.out.println("三等奖抽奖结束");
weightCategory3.setMaxNum(-1);
categoryList.remove(weightCategory3);
}
if(weightCategory4.getMaxNum()==0){
System.out.println("四等奖抽奖结束");
weightCategory4.setMaxNum(-1);
categoryList.remove(weightCategory4);
}
}
System.out.println("一等奖共出现 "+a1);
System.out.println("二等奖共出现 "+a2);
System.out.println("三等奖共出现 "+a3);
System.out.println("四等奖共出现 "+a4);
}