1. 程式人生 > >java實現權重演算法

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