java實現權重演算法
阿新 • • 發佈:2018-11-26
一、簡單介紹
如有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); }