有一组优惠 A-20优惠, B-30元优惠, C-5元优惠 当用户满足条件时随机返回一个优惠;在活动预算一定的情况下需要保证C类优惠券中奖概率最高,B类优惠券最低;以下是权重的实现;
/** * Copyright 2014-2015, , Inc. All Rights Reserved. * * Date: 2016年1月23日 */ package org.demo.core; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; /*** * * Desc:TODO * * @author zhangwei<[email protected]> * @since 2016年1月23日 下午1:35:16 * @version v 0.1 */ public class WeightRandomTest { private static Map<Double, String> weightMapping = new HashMap<>(); static { weightMapping.put(30d, "A"); weightMapping.put(20D, "B"); weightMapping.put(50D, "C"); } public static void main(String[] args) { int c = 0; int a = 0; int b = 0; for (int i = 0; i < 2000000; i++) { String str = WeightRandomUtil.getWeightRandom(weightMapping); if ("A".equals(str)) { a++; } else if ("B".equals(str)) { b++; } else if ("C".equals(str)) { c++; } } System.out.println(c / 2000000d); System.out.println(b / 2000000d); System.out.println(a / 2000000d); } } class WeightRandomUtil { /*** * 计算权重总和 * * @param weightArrays * @return * @author zhangwei<[email protected]> */ private static double weightSum(Set<Double> weights) { double weightSum = 0; for (double weightValue : weights) { weightSum += weightValue; } return weightSum; } /*** * * * @param weightArrays * 权重数组 * @return 返回数据 * @author zhangwei<[email protected]> * @param <T> */ public static <T> T getWeightRandom(Map<Double, T> weightValueMapping) { double weightSum = weightSum(weightValueMapping.keySet()); double stepWeightSum = 0; List<Double> list = new ArrayList<>(weightValueMapping.keySet()); Collections.sort(list, new Comparator<Double>() { @Override public int compare(Double o1, Double o2) { return (int) (o2 - o1); } }); double r = Math.random(); for (double weight : list) { // 计算权重值 stepWeightSum += weight; // 如果随机数落在了权重区间则返回索引值 if (r <= stepWeightSum / weightSum) { return weightValueMapping.get(weight); } } return null; } }