最近公司要弄一个图谱推荐的项目,在项目最后对剩余的销售人员使用贪心算法进行最后一步过滤,获取最佳销售人员组合,话不多说,先把代码贴出来
public class GreedyAlgorithm {
/**
*
* @param personSimilary 可选择的销售人员
* @param cost 成本
* @return
*/
public static List<String> getRecommendPersonnel(Map<String, Object> result, List<Long> personSimilary, int cost){
//首先求得每个销售人员的工资和日均销售额
Map<Long,Integer> fundPerson = (Map<Long, Integer>) result.get("人员销售额对应表");
Map<Long,Integer> salesManWages = new HashMap<>();
Map<String, List<Integer>> salesMan = (Map<String, List<Integer>>) result.get("销售人员");
Map<Long,String> idAndName = new HashMap<>();
Set<Map.Entry<String, List<Integer>>> salesManEntrySet = salesMan.entrySet();
Iterator<Map.Entry<String, List<Integer>>> iterator = salesManEntrySet.iterator();
while (iterator.hasNext()){
Map.Entry<String, List<Integer>> next = iterator.next();
Long id = Long.valueOf(next.getKey().split("-")[0]);
Integer wages = next.getValue().get(1);
salesManWages.put(id,wages);
idAndName.put(id,next.getKey().split("-")[1]);
}
Map<Long,String> newFundPerson = new HashMap<>();//相同销售人员的工资和销售额合并后的集合
Set<Map.Entry<Long, Integer>> fundPersonEntrySet = fundPerson.entrySet();
for (Map.Entry<Long, Integer> map : fundPersonEntrySet){
Long key = map.getKey();
Integer value = map.getValue();
Integer wages = salesManWages.get(key);
if (newFundPerson.containsKey(key)){
newFundPerson.put(key,newFundPerson.get(key) + value + "-" +wages);
}else {
newFundPerson.put(key,value+ "-" +wages);
}
}
Map<Long,String> resultMap = new HashMap<>();
newFundPerson.forEach((l,s) -> {
if (personSimilary.contains(l)){
resultMap.put(l,s);
}
});
//调用贪心算法
int size = resultMap.size();
int[] wages = new int[size];//工资数组
int[] salesVolume = new int[size];//销售额数组
String[] person = new String[size];
Set<Map.Entry<Long, String>> newFundPersonEntries = resultMap.entrySet();
Iterator<Map.Entry<Long, String>> iterator1 = newFundPersonEntries.iterator();
int i = 0;
while (iterator1.hasNext()){
Map.Entry<Long, String> next = iterator1.next();
Long key = next.getKey();
String value = next.getValue();
String[] split = value.split("-");
person[i] = idAndName.get(key);
wages[i] = Integer.valueOf(split[1]);
salesVolume[i] = Integer.valueOf(split[0]);
i++;
}
// newFundPerson.forEach((key,value) -> {
// String[] split = value.split("-");
// person[i] = key;
// wages[i] = Integer.valueOf(split[0]);
// salesVolume[i] = Integer.valueOf(split[1]);
// });
List<String> personList = GreedyAlgorithm.greedy(cost, wages, salesVolume, person);
return personList;
}
public static List<String> greedy(int cost, int[] wages, int[] salesVolume,String[] person){
int n = wages.length;
double[] r = new double[n]; //性价比数组
int[] index = new int[n]; //按性价比排序销售人员的下标
for(int i = 0;i < n;i++){
r[i] = (double) salesVolume[i] / wages[i];
index[i] = i;//默认排序
}
double temp = 0; //对性价比进行排序
for(int i = 0;i < n - 1;i++){
for(int j = i + 1;j < n;j++){
if(r[i] < r[j]){
temp = r[i];
r[i] = r[j];
r[j] = temp;
int x = index[i];
index[i] = index[j];
index[j] = x;
}
}
}
//将排序好的工资、销售额和人员分别按照性价比顺序存到数组中
int[] w1 = new int[n];
int[] value1 = new int[n];
String[] person1 = new String[n];
List<String> personList = new ArrayList<>();
for(int i = 0;i < n;i++){
w1[i] = wages[index[i]];
value1[i] = salesVolume[index[i]];
person1[i] = person[index[i]];
}
int maxValue = 0;
for(int i = 0;i < n;i++){
if(w1[i] <= cost){ //表明预算还有剩余
personList.add(person1[i]);//表示该销售人员被选中了
cost = cost - w1[i];
maxValue += value1[i];
}
}
System.out.println("进一步算法计算得出可以推荐的销售人员组合为:" + personList.toString());
System.out.println("该组合可创造的最大价值为:" + maxValue);
return personList;
}
/*public static void main(String[] args) {
int MAX_WEIGHT = 150;
int[] weights = new int[]{35,30,60,50,40,10,25};
int[] values = new int[]{10,40,30,50,35,40,30};
String[] person = new String[]{"zs","ls","ww","gg","ee","tt","yy"};
GreedyAlgorithm.greedy(MAX_WEIGHT,weights,values,person);
}*/
}
大致过程分为一下几步进行:
1、取得最大成本和每个个体的销售业绩和工资等
2、求得每个个体的性价比,按照从高到低进行排序
3、将排序好的工资、销售额和个体分别按照性价比顺序存储到数组中
4、在预算还有剩余的情况下,按照是否能放的下当前个体选择是否选择当前个体
总结:贪心算法最重要的就是抓住性价比和总成本两个核心!