标签:style class blog code java get
项目中一个算法中涉及到了组合,大概业务是:给定一个值X,从n个数中找出能组合加起来和X相等的集合。如果用通常的组合算法,数量级是2的n的阶乘,如果记录比较多的话,有效率问题。我针对我们的业务,优化写了一个算法。
大概逻辑:先给n个值从小到大排序形成一个队列,组合数从2开始依次递增,每次执行一个剔除操作,假设组合数递增到m,取队列中前面m-1个连续的值,并加上最大的一个值V,如果大于X,那么舍弃V。这样队列是不断缩小的。舍弃无用的组合,运算量也会大大减少。具体见代码:
/** * 从list中找出金额可以凑出db的多个lend2match * list需要根据金额从小到大排序 * @param listLend list,需要凑的金额,几个出借人组合数量(第一次从2开始),开始的序号(第一次为0) * @param db */ public static List<Lend2match> makeUp(List<Lend2match> listLend,Double db ,int num,int index) { if (num>listLend.size()) { //数量超出,整个list中没有合适的组合 return null; } //记录合适的makeup List<Lend2match> listMakeUp=new ArrayList<Lend2match>(); List<Lend2match> listReturn=new ArrayList<Lend2match>(); double dbMakeUp=0; //计算出最小的几个值,预留一个空缺 for (int i = 0; i <num-1; i++) { dbMakeUp+=listLend.get(i+index).getLendAmount(); listMakeUp.add(listLend.get(i+index));//先存起来记录 } Double tmp=dbMakeUp; //记录要舍去的list List<Lend2match> listDel=new ArrayList<Lend2match>(); for (int i = num+index-1; i < listLend.size(); i++) { dbMakeUp+=listLend.get(i).getLendAmount(); if (dbMakeUp==db) {//正好相等,记录并跳出 listMakeUp.add(listLend.get(i)); listReturn=listMakeUp; return listReturn; //只取第一次匹配合适的记录 } if (dbMakeUp>db) {//超出,舍去最大的那个记录 listDel.add(listLend.get(i)); } dbMakeUp=tmp;//值还原 } //删除要舍去的 for (Lend2match t:listDel) { listLend.remove(t); } //组合遍历 List<Lend2match> listRec=new ArrayList<Lend2match>(); listRec=traversal(listRec, listRec, db, num, index); if (listRec!=null&&listRec.size()!=0) { listReturn=listRec; } index++; //需要根据新的list,从序号为0开始依次作为组合中最小的 if (index+num+1>listLend.size()) { num++; index=0; } if (listReturn==null||listReturn.size()==0) { //继续迭代,增加组合的数量 listReturn=makeUp(listLend, db, num,index); } return listReturn; } /** * 组合遍历 * @param listLend * @param listReturn * @param db * @param num * @param index * @return */ public static List<Lend2match> traversal(List<Lend2match> listLend,List<Lend2match> listReturn,Double db ,int num,int index){ Double dbTmp=db; for (int i = index; i < listLend.size()-1-num; i++) { db=db-listLend.get(index).getLendAmount(); if (db==0) {//正好匹配 listReturn.add(listLend.get(index)); }else if (db>0) { int index1=i+1; int num1=num-1; listReturn=traversal(listLend,listReturn, db, num1, index1); if (listReturn!=null&&listReturn.size()!=0) { listReturn.add(listLend.get(index)); }else { listReturn=null; } }else if (db<0) { listReturn=null; } db=dbTmp; } return listReturn; }
标签:style class blog code java get
原文地址:http://blog.csdn.net/jesse621/article/details/34472855