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代码:
将分完的结果通过对象返回给前台页面
给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(); }
将分完的结果通过对象返回给前台页面
相关文章推荐
- java实战算法根据个数百分比,排序金额分配案件金额也趋近百分比(二)
- 算法实战java实现快速排序
- 算法实战:根据Key或Value对Map进行排序及其应用
- 算法实战:根据Key或Value对Map进行排序及其应用
- java算法之 排序(插入、交换、选择、归并、分配排序)
- Java 数据结构和算法 排序
- java 根据list元素排序
- 排序算法之归并排序 java
- Java写的不用数组对四个数进行排序的算法
- 啊哈算法java实现 --木桶排序
- (java)根据map中value进行排序
- Java经典算法汇总之选择排序(SelectionSort)
- Java实现排序算法之堆排序
- 金额随机分配算法(修改版)
- <三>java数据结构与算法 选择排序
- 基于JAVA的排序算法之七--堆排序
- java排序算法
- Java常见排序算法之快速排序
- Java常见排序算法之直接插入排序
- Java数据结构与算法之选择排序_动力节点Java学院整理