赞
踩
使用场景:
给n个员工分配n个案子。条件是按个数比例分配。分配后的案件金额也趋近于个数的比例,并且趋近公平分配。
设计思路
这里比较复杂的地方就是怎么按个数占比分配,案件金额总数也趋近个数占比。并且趋近公平
例如10个按键,案件金额为1,2,3,4,5,6,7,8,9,10
第一种情况偶数分配:
给两个人分案件,一个分配40%一个分配60%,案件个数就是4:6 = 2:3 怎么让金额也趋近2:3
设计思路是先将案件按金额大小排序从头尾获取,第一个人获取四个案件,这四个案件分别从头尾获取,例如当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();
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。