一、简单介绍
如有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);
- }