初步权重算法

master
ninftao 3 years ago
parent faeb6a01ce
commit a38fffcbfd

@ -3,6 +3,7 @@ package com.baiye.model.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
@ -10,7 +11,9 @@ import java.util.List;
* @date : 2021/12/13
*/
@Data
public class DistributeResponseDTO {
public class DistributeResponseDTO implements Serializable {
private static final long serialVersionUID = 2772000439619817023L;
@ApiModelProperty("部门id集合")
private Long deptId;

@ -13,6 +13,11 @@ public enum ResponseCode {
*/
SUCCESS("1", "成功"),
/**
*
*/
PARAMETER_ERROR("1001", "参数错误"),
DECRYPTION_FAILED("1012", "数据解析失败");

@ -5,6 +5,7 @@ import com.baiye.constant.DefaultNumberConstants;
import com.baiye.http.CommonResponse;
import com.baiye.model.dto.DistributeDTO;
import com.baiye.model.dto.DistributeResponseDTO;
import com.baiye.model.enums.ResponseCode;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
@ -13,6 +14,7 @@ import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author Enzo
@ -24,45 +26,52 @@ public class AssignDataService {
public CommonResponse<List<DistributeResponseDTO>> assignData(DistributeDTO distribution) {
int size = distribution.getDeptIds().size();
List<Long> deptIds = distribution.getDeptIds();
List<Double> weights = distribution.getWeights();
List<String> resourceList = distribution.getResourceList();
CopyOnWriteArrayList<String> resourceList =
Lists.newCopyOnWriteArrayList(distribution.getResourceList());
// 数据打乱
Collections.shuffle(resourceList);
// 去除重复数据
List<String> stringList =
Lists.newArrayList(Sets.newHashSet(resourceList));
CopyOnWriteArrayList<String> copyOnWriteArrayList =
Lists.newCopyOnWriteArrayList(Sets.newHashSet(resourceList));
int resourceSize = copyOnWriteArrayList.size();
// 集合求和
double sum = weights.stream().mapToDouble(Double::doubleValue).sum();
if (sum != DefaultNumberConstants.ONE_HUNDRED) {
return CommonResponse.createByErrorMessage("");
return CommonResponse.createByErrorMessage(ResponseCode.DECRYPTION_FAILED.getDesc());
}
List<Long> deptIds = distribution.getDeptIds();
CopyOnWriteArrayList<String> value;
List<DistributeResponseDTO> list = new ArrayList<>();
int offset = DefaultNumberConstants.ZERO_NUMBER;
List<String> value;
DistributeResponseDTO distributeResponseDTO;
for (int i = DefaultNumberConstants.ZERO_NUMBER; i < deptIds.size(); i++) {
Double aDouble = weights.get(i);
distributeResponseDTO = new DistributeResponseDTO();
double div = NumberUtil.div(aDouble,
Double.valueOf(DefaultNumberConstants.ONE_HUNDRED), DefaultNumberConstants.TWO_HUNDRED);
int floor = (int) Math.floor(NumberUtil.mul(stringList.size(), div));
if (size > DefaultNumberConstants.ZERO_NUMBER) {
value = stringList.subList(i * floor + offset,
(i + DefaultNumberConstants.ONE_NUMBER) * floor + offset + DefaultNumberConstants.ONE_NUMBER);
size--;
offset++;
if (size - DefaultNumberConstants.ONE_NUMBER > i) {
double div = NumberUtil.div(aDouble,
Double.valueOf(DefaultNumberConstants.ONE_HUNDRED), DefaultNumberConstants.TWO_HUNDRED);
int count = (int) Math.floor(NumberUtil.mul(resourceSize, div));
if (count == DefaultNumberConstants.ONE_NUMBER) {
int middle = (int) Math.floor(copyOnWriteArrayList.size() / 2);
value = Lists.newCopyOnWriteArrayList(Lists.newArrayList(copyOnWriteArrayList.get(middle)));
distributeResponseDTO.setResponseList(value);
distributeResponseDTO.setDeptId(deptIds.get(i));
list.add(distributeResponseDTO);
copyOnWriteArrayList.remove(middle);
continue;
}
value = Lists.newCopyOnWriteArrayList
(copyOnWriteArrayList.subList(DefaultNumberConstants.ZERO_NUMBER, count));
distributeResponseDTO.setResponseList(value);
distributeResponseDTO.setDeptId(deptIds.get(i));
list.add(distributeResponseDTO);
copyOnWriteArrayList.removeAll(value);
} else {
value = stringList.subList
(i * floor + offset, (i + DefaultNumberConstants.ONE_NUMBER) * floor + offset);
value = Lists.newCopyOnWriteArrayList(Lists.newArrayList(copyOnWriteArrayList));
distributeResponseDTO.setResponseList(value);
distributeResponseDTO.setDeptId(deptIds.get(i));
list.add(distributeResponseDTO);
}
distributeResponseDTO.setResponseList(value);
distributeResponseDTO.setDeptId(deptIds.get(i));
list.add(distributeResponseDTO);
}
return CommonResponse.createBySuccess(list);
}

@ -19,11 +19,11 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class WeightRandomStrategyX<K, V extends Number> {
private TreeMap<Double, K> weightMap = new TreeMap<>();
private double factor=0D;
public WeightRandomStrategyX(List<Pair<K, V>> list) {
for (Pair<K, V> pair : list) {
double lastWeight = this.weightMap.size() == 0 ? 0 : this.weightMap.lastKey();
this.weightMap.put(pair.getValue().doubleValue() + lastWeight, pair.getKey());
this.weightMap.put(factor, pair.getKey());
this.factor+=pair.getValue().doubleValue();
}
}
@ -32,9 +32,9 @@ public class WeightRandomStrategyX<K, V extends Number> {
* @return
*/
public K random() {
double randomWeight = this.weightMap.lastKey() * Math.random();
SortedMap<Double, K> tailMap = this.weightMap.tailMap(randomWeight, false);
return this.weightMap.get(tailMap.firstKey());
double randomWeight = ThreadLocalRandom.current().nextDouble(factor);
SortedMap<Double, K> tailMap = this.weightMap.headMap(randomWeight, false);
return this.weightMap.get(tailMap.lastKey());
}
public static void main(String[] args) {
@ -42,10 +42,11 @@ public class WeightRandomStrategyX<K, V extends Number> {
list.add(new ImmutablePair<>("A", 10));
list.add(new ImmutablePair<>("B", 20));
list.add(new ImmutablePair<>("C", 30));
list.add(new ImmutablePair<>("D", 60));
list.add(new ImmutablePair<>("D", 40));
WeightRandomStrategyX<String, Integer> strategy = new WeightRandomStrategyX<>(list);
Map<String, AtomicInteger> count = new HashMap<>(8);
for (int i = 0; i < 10000; i++) {
for (int i = 0; i < 10; i++) {
String key=strategy.random();
AtomicInteger ai = new AtomicInteger(0);
AtomicInteger old = count.putIfAbsent(key,ai);
@ -57,4 +58,5 @@ public class WeightRandomStrategyX<K, V extends Number> {
System.out.println(count);
}
}

@ -1,8 +1,10 @@
package com.baiye;
import cn.hutool.json.JSONUtil;
import com.baiye.model.dto.DistributeDTO;
import com.baiye.service.AssignDataService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
@ -10,12 +12,14 @@ import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Enzo
* @date : 2021/11/19
*/
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AdPlatformServiceApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ -24,18 +28,19 @@ public class SettingTest {
@Resource
private AssignDataService assignDataService;
@Test
public void getSetting(){
public void getSetting() {
DistributeDTO distributeDTO = new DistributeDTO();
List<String> strings = Lists.newArrayList("a", "b", "c", "d");
List<String> strings = Lists.newArrayList("a", "b", "c", "d","e","f","g","h","i","j");
List<Long> longs = Lists.newArrayList(12360L,12361L);
List<Double> doubleList = Lists.newArrayList(50.0,50.0);
distributeDTO.setWeights(doubleList);
List<Long> longs = Lists.newArrayList(12360L, 12361L,12362L,12363L,12364L,12365L);
List<Double> doubleList = Lists.newArrayList(16.66, 16.66,16.66,16.66,16.66,16.7);
distributeDTO.setResourceList(strings);
distributeDTO.setWeights(doubleList);
distributeDTO.setDeptIds(longs);
assignDataService.assignData(distributeDTO);
log.info(JSONUtil.toJsonStr(assignDataService.assignData(distributeDTO)));
}
@ -81,21 +86,87 @@ public class SettingTest {
}
public static <T> List<List<T>> averageAssign(List<T> source, int n) {
List<List<T>> result = new ArrayList<>();
int remainder = source.size() % n; //(先计算出余数)
int number = source.size() / n; //然后是商
int offset = 0;//偏移量
for (int i = 0; i < n; i++) {
List<T> value;
if (remainder > 0) {
value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
remainder--;
offset++;
} else {
value = source.subList(i * number + offset, (i + 1) * number + offset);
List<List<T>> result = new ArrayList<>();
int remainder = source.size() % n; //(先计算出余数)
int number = source.size() / n; //然后是商
int offset = 0;//偏移量
for (int i = 0; i < n; i++) {
List<T> value;
if (remainder > 0) {
value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
remainder--;
offset++;
} else {
value = source.subList(i * number + offset, (i + 1) * number + offset);
}
result.add(value);
}
return result;
}
//*********************************************催收公司分案相关**************************//
public static <T> List<List<T>> updateAutoCaseSplit(List<T> users, List<Double> ratioList, List<String> sourceList) {
Integer casecount = sourceList.size();//案件个数
//将用户排序打乱
Collections.shuffle(users);
List<String> caselist = new ArrayList<String>();//剩余案件
caselist = sourceList;
//循环遍历员工
for (int i = 0; i < users.size(); i++) {
//计算用户分得几个案子 案件数*百分比
if (i != users.size() - 1) {
double userCaseCount = casecount * ratioList.get(i) / 100;
Integer count = (int) Math.floor(userCaseCount);
//根据分的案件个数从头尾取值 如果有奇数就奇数在中间取一个变为偶数在头尾取值
if (count % 2 == 0) {//偶数
Integer total = count / 2; //头尾各取total个
for (int j = 0; j < total; j++) {
int end = caselist.size() - 1;
System.out.println(caselist.get(0));
System.out.println(caselist.get(end));
// users.get(i).addCaseHead(caselist.get(0));//头
// users.get(i).addCaseHead(caselist.get(end));//尾
caselist.remove(end);
caselist.remove(0);
}
} else {//奇数
if (count == 1) {//如果只有一个案子那么在中间取一个就退出
int middle = (int) Math.floor(caselist.size() / 2);
System.out.println(caselist.get(middle));
// users.get(i).addCaseHead(caselist.get(middle));//中
caselist.remove(middle);
} else {
//第一个取中间
int middle = (int) Math.floor(caselist.size() / 2);
System.out.println(caselist.get(middle));
// users.get(i).addCaseHead(caselist.get(middle));//中
caselist.remove(middle);
//剩下的跟偶数一致
int total = (count - 1) / 2;
for (int a = 0; a < total; a++) {
int end = caselist.size() - 1;
System.out.println(caselist.get(0));
// users.get(i).addCaseHead(caselist.get(0));//头
// users.get(i).addCaseHead(caselist.get(end));//尾
caselist.remove(end);
caselist.remove(0);
}
}
}
} else {//最后一个不用计算案件数。剩余案件全是最后一个的这是为了以上几个计算有小数点取整误差
for (String aLong : caselist) {
System.out.println(aLong);
}
result.add(value);
}
return result;
}
return new ArrayList<>();
}
}
}
Loading…
Cancel
Save