fraze

导航

随机选取之权重选择的实现

import java.util.List;

/**
 *
 * 根据权重选取对应值的简单实现
 *
 */
public final class SelectorWithWeight {
    final static double M0 = 10E-10;
    /**
     *
     * 获取命中权重对应的值
     *
     * @param weightList
     * @return
     */
    public static <T> T randomByWeight(final List<WeightPair<T>> weightList){

        if(weightList.size() == 0){
            return null;
        }

        double sum = 0.0d;
        double cw = 0.0d;

        for(WeightPair<T> wt : weightList){
            sum += wt.weight;
        }

        //近似0,有进度损失
        if(sum < M0){
            return null;
        }

        double rv = 0.0;

        for(int i = 0; i < weightList.size(); i++){

            sum = sum - cw;

            rv = Math.random();

            if(rv <= (weightList.get(i).weight / sum)){
                return weightList.get(i).value;
            }

            cw = weightList.get(i).weight;

        }

        return weightList.get(weightList.size() / 2).value;

    }

    /**
     *
     * 获取命中权重所在下标
     *
     * @param weights
     * @return
     */
    public static int randomByWeight(final double[] weights){

        double sum = 0.0d;
        double cw = 0.0d;

        for(double w : weights){
            sum += w;
        }

        double rv = 0.0;

        for(int i = 0; i < weights.length; i++){

            sum = sum - cw;

            rv = Math.random();

            if(rv <= (weights[i] / sum)){
                return i;
            }

            cw = weights[i];

        }

        return weights.length / 2;

    }


    /**
     *权重与值配置,immutable
     */
    public final static class WeightPair<T> {

        public final double weight;
        public final T value;

        public WeightPair(double w, T v) {
            this.weight = w;
            this.value = v;
        }

    }
}

 

posted on 2019-02-12 07:47  fraze  阅读(612)  评论(0编辑  收藏  举报