公平概率抽奖算法工具类分享
依赖hutool工具类,可进一步改造成带库存的奖品,我这里暂时用不到库存就不改造了,有大佬改造好了请留言~
hutool
/** * 抽奖,返回抽到的奖品 * @param prizeList 奖品列表 * @return T * @exception * @author GMQ * @date 2022/2/18 21:18 **/ public static <T> T lottery(List<T> prizeList){ if (CollUtil.isEmpty(prizeList)){ return null; } //概率总和 BigDecimal rateSum = BigDecimal.ZERO; for (T t1 : prizeList) { Map map = Convert.convert(HashMap.class, t1); rateSum = NumberUtil.add(rateSum,NumberUtil.toBigDecimal(map.get("winnRate")+"")); } BigDecimal temp = BigDecimal.ZERO; //比值 List<BigDecimal> tempList = new ArrayList<>(prizeList.size()); for (T t1 : prizeList) { Map map = Convert.convert(HashMap.class, t1); temp = temp.add(NumberUtil.toBigDecimal(map.get("winnRate")+"")); tempList.add(NumberUtil.div(temp,rateSum,8)); } BigDecimal value = NumberUtil.round(RandomUtil.randomBigDecimal(),8); tempList.add(value); Collections.sort(tempList); int index = tempList.indexOf(value); T win = prizeList.get(index); return win; }
@Test void f5(){ List<Map> list = new ArrayList<>(); Map map1 = new HashMap(); map1.put("name","现金红包200"); map1.put("winnRate","47"); list.add(map1); Map map2 = new HashMap(); map2.put("name","小米运动手表"); map2.put("winnRate","30"); list.add(map2); Map map3 = new HashMap(); map3.put("name","手机"); map3.put("winnRate","10"); list.add(map3); Map map4 = new HashMap(); map4.put("name","苹果电脑"); map4.put("winnRate","5"); list.add(map4); // Map map5 = new HashMap(); // map5.put("name","三亚五日游"); // map5.put("winnRate","1"); // list.add(map5); BigDecimal rateSum = BigDecimal.ZERO; for (Map map : list) { rateSum = NumberUtil.add(rateSum,NumberUtil.toBigDecimal(map.get("winnRate")+"")); } System.out.println("概率总和:"+rateSum); Map map = new HashMap(); // 抽取100次 for (int i = 0; i < 100; i++) { Map win = LotteryUtil.lottery(list); map.put(win.get("name"),map.get(win.get("name"))==null?1:Integer.valueOf(map.get(win.get("name"))+"")+1); } System.out.println("抽中统计:"+JSON.toJSONString(map)); }
0条留言