按权重分配任务

public class TaskAlloc {

    private Map<String, Integer> weight;

    public Map<String, Integer> getWeight() {
        return weight;
    }

    public Map<String, Integer> getCmpltedTask() {
        return cmpltedTask;
    }

    public AtomicInteger getAllcodCount() {
        return allcodCount;
    }

    private Map<String, Integer> cmpltedTask = new ConcurrentHashMap<String, Integer>();
    private AtomicInteger allcodCount = new AtomicInteger(0);

    public TaskAlloc(Map<String, Integer> weight) throws Exception {
        this.weight = weight;
        Integer sum = MapHelper.reduce(weight, 0, (init, current) -> init + current);
        if (sum != 100) {
            throw new Exception("权重之合必须为100");
        }

        for (String key : weight.keySet()) {
            cmpltedTask.put(key, 0);
        }
    }

    public String alloc() {
        int ac = allcodCount.getAndIncrement();
        String key = getMin(cmpltedTask, weight, ac);
        cmpltedTask.put(key, cmpltedTask.get(key) + 1);
        return key;
    }

    private static String getMin(Map<String, Integer> allocedRecordMap, Map<String, Integer> weightMap, Integer allocedCount) {
        double min = 1;
        String result = null;
        for (Map.Entry<String, Integer> entry : weightMap.entrySet()) {
            String key = entry.getKey();
            //计算权重所占最大的比例
            double maxRatio = entry.getValue() * 1.0 / 100;
            //计算已分配的比例
            double cmpltedRatio = allocedCount == 0 ? 0 : allocedRecordMap.get(key) * 1.0 / allocedCount;
            double ratio = cmpltedRatio / maxRatio;
            if (ratio < min) {
                result = key;
                min = ratio;
            }
        }

        return result;
    }
}

第2种算法

public class TaskAlloc {

    /**
     * 任务权重Map,Key为任务标识,Value为任务对应的权重
     */
    private Map<String, Integer> weight;

    public Map<String, Integer> getWeight() {
        return weight;
    }

    /**
     *  ctor
     * @param weight 任务权重Map,Key为任务标识,Value为任务对应的权重
     * @throws Exception
     */
    public TaskAlloc(Map<String, Integer> weight) throws Exception {
        this.weight = weight;
        Integer sum = MapHelper.reduce(weight, 0, (result, current) -> result + current);
        if (sum != 100) {
            throw new Exception("权重之合必须为100");
        }
    }

    /**
     * 分配任务实现.
     * @param taskAllocStatisticsMapFunc 提供所有任务的分配统计Map Key为任务标识,Value为该任务已分配总数
     * @return 需要分配的任务标识
     * @throws Exception 任务的分配统计Map不能为空
     */
    public String alloc(Supplier<Map<String, Integer>> taskAllocStatisticsMapFunc)throws Exception  {
        Map<String, Integer> taskAllocStatisticsMap = taskAllocStatisticsMapFunc.get();
        if (taskAllocStatisticsMap == null) {
            throw new Exception("任务的分配统计Map不能为空");
        }
        int allocedCount = MapHelper.reduce(taskAllocStatisticsMap, 0, (result, currentValue) -> result + currentValue);
        String key = getMin(taskAllocStatisticsMap, weight, allocedCount);
        taskAllocStatisticsMap.put(key, taskAllocStatisticsMap.get(key) + 1);
        return key;
    }

    /**
     * 找到分配比率最小的任务标识(即需要分配的任务标识)
     * @param taskAllocStatisticsMap 任务的分配统计Map(Key为任务标识,Value为该任务已分配总数)
     * @param weightMap 任务的权重Map
     * @param allocedCount 已分配的总次数
     * @return 需要分配的任务标识
     */
    private static String getMin(Map<String, Integer> taskAllocStatisticsMap, Map<String, Integer> weightMap,
            Integer allocedCount) {
        double min = 1;
        String result = null;
        for (Map.Entry<String, Integer> entry : weightMap.entrySet()) {
            String key = entry.getKey();
            //计算权重所占最大的比例
            double maxRatio = entry.getValue() * 1.0 / 100;
            //计算已分配的比例
            double cmpltedRatio = allocedCount == 0 ? 0 : taskAllocStatisticsMap.getOrDefault(key, 0) * 1.0 / allocedCount;
            double ratio = cmpltedRatio / maxRatio;
            if (ratio < min) {
                result = key;
                min = ratio;
            }
        }

        return result;
    }
}
原文地址:https://www.cnblogs.com/zhshlimi/p/9042684.html