java实现权重算法

一、简单介绍

如有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);
    }

猜你喜欢

转载自my.oschina.net/u/3387320/blog/2961404