Java实现采样,均分优化
看过上一篇的应该知道,在均分采样的时候,必须保证数量的顺序是从小到大。
因为,我把多出来,全部从最后一个采了,所以要保证最后一个数量是这里面最多的。
哎~,老大看后,就不爽了,说这样不行,不能全部放到最后一个。
那那那~~~,继续撸呗
直接上代码。
达到的效果:
- 里面模板中数量的顺序,现在不要求了。但是如果你想要数量多的,多采一些,那么需要保证按照数量降序处理
- 对于两个临界点的处理。
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