说明:最近接到一个需求,要求对当月的发票进行运算,当月有10张发票,每张面额,300-500不等,报销金额是1200,要求从这些发票中选出几张求和最接近1200,用来报销使用。
既:300,350,330,410,366,369,380,371.34,361.25,使用算法挑选几个数字求和,使该数字最接近1200.
技术方案:蒙特卡洛组合法。
代码如下:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.codehaus.jettison.json.JSONObject;
import com.google.gson.JsonObject;
import net.sf.json.JSONArray;
public class mtkl {
public ArrayList<Double> MC_combination(ArrayList<Double> nums,double target)
{
ArrayList<Double> res = new ArrayList<>();
double lapse = 10000;
Random random = new Random();
for (int i=0;i<1000000;i++)
{
int numsize = random.nextInt(nums.size() + 1);
ArrayList<Double> ares = new ArrayList<>();
HashMap<Integer,Integer> map = new HashMap<>();
double thissum = 0;
for (int j=0 ;j<numsize;j++)
{
int anumberindex = random.nextInt(nums.size());
while (map.containsKey(anumberindex))
{
anumberindex = random.nextInt(nums.size());
}
map.put(anumberindex,1);
ares.add(nums.get(anumberindex));
thissum += nums.get(anumberindex);
}
if(Math.abs(thissum - target)<lapse)
{
lapse = Math.abs(thissum - target);
res = ares;
}
if(lapse<0.000001)
break;
}
return res;
}
/**
* 蒙特卡洛组合法
* 烟雨江南---
* @param nums
* @param target
* @return
*/
public String getGreatValue(List<Map<String,Object>> list,String amountout){
JSONObject result=new JSONObject();
try{
double target=Double.parseDouble(amountout);
double lapse = 1000;
Random random = new Random();
for (int i=0;i<1000000;i++) {
int numsize = random.nextInt(list.size() + 1);
List<Map<String,Object>> ares = new ArrayList<Map<String,Object>>();
HashMap<Integer,Integer> map = new HashMap<>();
double thissum = 0;
for (int j=0 ;j<numsize;j++){
int anumberindex = random.nextInt(list.size());
while (map.containsKey(anumberindex))
{
anumberindex = random.nextInt(list.size());
}
map.put(anumberindex,1);
HashMap<String, Object> obj = new HashMap<String,Object>();
obj.put("id", list.get(anumberindex).get("id"));
obj.put("amount", list.get(anumberindex).get("amount"));
ares.add(obj);
thissum += Double.parseDouble(list.get(anumberindex).get("amount").toString());
}
if(Math.abs(thissum - target)<lapse){
lapse = Math.abs(thissum - target);
result.put("data", JSONArray.fromObject(ares));
result.put("count", thissum);
result.put("litter", Math.abs(thissum - target));
}
if(lapse<0.000001){
break;
}
}
}catch(Exception e){
e.printStackTrace();
}
return result.toString();
}
public static void main(String args[]) {
List<Map<String,Object>> res = new ArrayList<Map<String,Object>>();
Map obj1 = new HashMap<String,Object>();
obj1.put("id", "A");
obj1.put("amount", "303");
res.add(obj1);
Map obj2 = new HashMap<String,Object>();
obj2.put("id", "B");
obj2.put("amount", "359");
res.add(obj2);
Map obj3 = new HashMap<String,Object>();
obj3.put("id", "C");
obj3.put("amount", "389");
res.add(obj3);
Map obj4 = new HashMap<String,Object>();
obj4.put("id", "D");
obj4.put("amount", "350");
res.add(obj4);
Map obj5 = new HashMap<String,Object>();
obj5.put("id", "E");
obj5.put("amount", "335");
res.add(obj5);
Map obj6 = new HashMap<String,Object>();
obj6.put("id", "F");
obj6.put("amount", "410");
res.add(obj6);
System.out.println(new mtkl().getGreatValue(res,"1250"));
}
};