您的位置:首页 > 编程语言 > Java开发

java实战算法根据个数百分比,排序金额分配案件金额也趋近百分比

2018-01-23 18:39 411 查看
使用场景:

给n个员工分配n个案子。条件是按个数比例分配。分配后的案件金额也趋近于个数的比例,并且趋近公平分配。

设计思路

这里比较复杂的地方就是怎么按个数占比分配,案件金额总数也趋近个数占比。并且趋近公平

例如10个按键,案件金额为1,2,3,4,5,6,7,8,9,10

第一种情况偶数分配:

给两个人分案件,一个分配40%一个分配60%,案件个数就是4:6  = 2:3  怎么让金额也趋近2:3 

设计思路是先将案件按金额大小排序从头尾获取,第一个人获取四个案件,这
4000
四个案件分别从头尾获取,例如当A先获取四个案件是,A拿到的案件分别是1,10,2,9。B获取到的就是3,8,4,7,5,6,金额的比例是 22:33 趋近 2:3的案件占比。

第二种情况奇数数分配:

给两个人分案件,一个分配30%一个分配70%,案件个数就是3:7怎么让金额也趋近3:7=0.42设计思路是还是先将案件按金额大小排序从头尾获取,第一个人获取四个案件,这四个案件分别从头尾获取,例如当                                                                A先获取一个中间的案件然后剩下的按偶数的从头尾取案件,同理第二个人也一样A拿到的案件分别是5,1,10
 B获取到的就是6,2,9,3,8,4,7 金额的比例是 16:39=0.41趋近于0.42的案件占比。

当总件数跟百分比的乘机为有小数点的时候,向下取整,比如1.4  取 1。最后一个人直接取剩下所有。

偶数分配图示



奇数分配图示



Java代码:

//*********************************************催收公司分案相关**************************//
@Override
public List<User> updateAutoCaseSplit(CaseHead head,CaseParamsExtend exParams,List<User> users,String tableName) {
if (head == null){
return users;
}
if (users == null || users.size() == 0){
return users;
}
//获取案件
List<CaseHead> heads=caseHeadMapper.getCaseHeadAll(head,exParams,tableName);
if (heads == null || heads.size() == 0){
return users;
}
// 进行分案处理 1.案件金额排序
sortCases(heads);
Integer casecount=heads.size();//案件个数
//将用户排序打乱
Collections.shuffle(users);

List<CaseHead> caselist=new ArrayList<CaseHead>();//剩余案件
caselist=heads;
//循环遍历员工
for (int i = 0; i <users.size() ; i++) {

//计算用户分得几个案子  案件数*百分比
if (i != users.size()-1){
double userCaseCount=casecount*users.get(i).getSplitRate()/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;
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);
users.get(i).addCaseHead(caselist.get(middle));//中
caselist.remove(middle);
}else{
//第一个取中间
int middle=(int)Math.floor(caselist.size()/2);
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;
users.get(i).addCaseHead(caselist.get(0));//头
users.get(i).addCaseHead(caselist.get(end));//尾
caselist.remove(end);
caselist.remove(0);

}
}
}

}else{//最后一个不用计算案件数。剩余案件全是最后一个的这是为了以上几个计算有小数点取整误差
for (CaseHead caseHead : caselist) {
users.get(i).addCaseHead(caseHead);
}
}
}

return  users;
}

/**
* 执行分案
* */
@Override
public List<User> updateCaseSplit(List<User> users, String tableName) throws Exception {

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

}
return null;
}

//案件按照金额排序
private void sortCases(List<CaseHead> caseHeads) {
Collections.sort(caseHeads, new Comparator<CaseHead>() {
@Override
public int compare(CaseHead o1, CaseHead o2) {
return (int) (o2.getMoney() - o1.getMoney()) * 1000;
}
});
}

//*********************************************催收公司分案相关结束************************//


//==================分案相关操作
@Transient
private double splitRate;//分案占比;
@Transient
private double splitTotal;//分案总金额
@Transient
private int splitCount;//分案总件数
@Transient
private List<User> userList;//分案参数
@Transient
private List<CaseHead> caseList;//案件list

public List<CaseHead> getCaseList() {
return caseList;
}

public void setCaseList(List<CaseHead> caseList) {
this.caseList = caseList;
}

public List<User> getUserList() {
return userList;
}

public void setUserList(List<User> userList) {
this.userList = userList;
}

public void addCaseHead(CaseHead caseHead){
if(caseList==null)
caseList=new ArrayList<>();
caseList.add(caseHead);
//总额 件数
splitCount++;
splitTotal+=caseHead.getMoney();
}


将分完的结果通过对象返回给前台页面
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: