Java实现采样,均分优化

看过上一篇的应该知道,在均分采样的时候,必须保证数量的顺序是从小到大。
因为,我把多出来,全部从最后一个采了,所以要保证最后一个数量是这里面最多的。

哎~,老大看后,就不爽了,说这样不行,不能全部放到最后一个。

那那那~~~,继续撸呗

直接上代码。

达到的效果:

  1. 里面模板中数量的顺序,现在不要求了。但是如果你想要数量多的,多采一些,那么需要保证按照数量降序处理
  2. 对于两个临界点的处理。
    2.1 当采样总数 > 模板总数的。每个模板全采
    2.1 当采样总数 < 模板个数的时候。循环遍历到的先采。这样有些模板就可能采不到。(这种根据自己的业务来设置)
    2.3 当模板的个数 <= 采样总数 <= 模板的总数量。正常处理。

均分采样

/***
     * 均分采样
     * @param map   存放数据,需要按照数量正序排
     * @param sampleTotal 需要采样的数量
     */
    public static Map<String, Integer> allocateFlowByAverage2(Map<String, Integer> map, Integer sampleTotal) {
        Map<String, Integer> remainMap = new HashMap<>(map);
        // 加上这个。!remainMap.isEmpty(),解决当采样数量多余模板中的数量
        while (sampleTotal > 0 && !remainMap.isEmpty()) {
            double averageCount = sampleTotal.doubleValue() / remainMap.size();
            System.out.println("平均值是:" + averageCount);
            Iterator<Map.Entry<String, Integer>> iterator = remainMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Integer> next = iterator.next();
                int actualCount = next.getValue();
                if (averageCount < next.getValue()) {
                    // 注意这里面的判断。当averageCount > 1的时候,说明每个模板可以至少分一个,就按照少的来分,所以直接强制转成int
                    // 当 averageCount < 1的时候,说明有些模板采不到,此时要使用(int) Math.ceil(averageCount)。保证能采到的采到
                    actualCount = averageCount > 1 ? (int)averageCount : (int) Math.ceil(averageCount);
                    remainMap.put(next.getKey(), next.getValue() - actualCount);
                } else {
                    iterator.remove();
                }
                sampleTotal -= actualCount;

                if (sampleTotal == 0) {
                    break;
                }
            }
       }
        return remainMap;
    }

测试均分

老规矩。直接进行测试

模板总数是15

public static void main(String[] args) {
        // 乱序的
        Map<String, Integer> map = new HashMap<>();
        map.put("A", 3);
        map.put("B", 1);
        map.put("C", 4);
        map.put("D", 6);
        map.put("E", 1);

        int sampleTotal = 3;
        Map<String, Integer> remainMap = allocateFlowByAverage2(map, sampleTotal);
        Iterator<Map.Entry<String, Integer>> iterator2 = map.entrySet().iterator();
        System.out.println("======== 统计信息的 ===== ");
        while (iterator2.hasNext()) {
            Map.Entry<String, Integer> next = iterator2.next();
            Integer remainCount = remainMap.get(next.getKey());
            if (remainCount == null) {
                remainCount = 0;
            }
            System.out.println(next.getKey() + "模板,原来有:" + next.getValue() + ",应采样:" + (next.getValue() - remainCount));
        }
    }

采样数量 < 模板的个数

sampleTotal = 3

采样数量 > 模板总数

sampleTotal = 200

模板个数 <= 采样数量 <= 模板总数

sampleTotal = 9

posted @ 2020-12-02 22:39  刘翊扬  阅读(544)  评论(0编辑  收藏  举报