当前位置:   article > 正文

常用十大算法_贪心算法_贪心算法等十大算法

贪心算法等十大算法

贪心算法 

 贪心算法本质就是在对问题求解时,每一步都选最优的结果,这些每步最优结果汇集成问题的最终结果。但这个最终结果不一定是最优结果。因为每一步可能存在多个最优解,贪心算法只会按照顺序选择其中一个。

【例子】存在下表中的站点K1~5,每个站点对应不同的覆盖城市,需要选择最少的站点,覆盖全部城市

站点覆盖城市
K1北京,上海,天津
K2广州,北京,深圳
K3成都,上海,杭州
K4上海,天津
K5杭州,大连

算法分析: 

注意上述每步中的最优解有可能不止一个,比如说:allAreas中只剩杭州时,K3和K5交集大小都为1,按照顺序取得的策略,贪心算法会选择K3,而不是K5。如果选择K5花的钱比K3少时,贪心算法获得的结果就不算最优了,但它一定满足都覆盖。根据贪心算法的原理,我们需要一个maxKey指针和Key指针,还需要一个集合allAreas用于存储全部城市。每次循环key指针从K1指到K5,而maxKey指针用于指向循环中,覆盖城市与全部城市交集最大的Kn站点(取得每步的最优解),当5个站点都循环完后,需要把maxKey指向的站点加入到一个专门存储解的集合selects中,同时要删除allAreas中Kn覆盖城市的部分,并重置maxKey。再进行循环,直到allAreas集合大小为0时结束。

代码实现:(注意这里面用了maxKeySize,用于保存交集大小,方便下一次循环产生的交集与之比较,找到最优站点)

  1. package cn.dataStructureAndAlgorithm.demo.tenAlgorithm.greedyAlgorithm;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.HashSet;
  5. public class 贪心算法_greedyAlgorithm_子集覆盖问题 {
  6. public static void main(String[] args) {
  7. //创建各站点
  8. HashMap<String, HashSet<String>> broad= new HashMap<>();
  9. HashSet<String> place1=new HashSet<>();
  10. place1.add("北京");
  11. place1.add("上海");
  12. place1.add("天津");
  13. HashSet<String> place2=new HashSet<>();
  14. place2.add("北京");
  15. place2.add("广州");
  16. place2.add("深圳");
  17. HashSet<String> place3=new HashSet<>();
  18. place3.add("成都");
  19. place3.add("上海");
  20. place3.add("杭州");
  21. HashSet<String> place4=new HashSet<>();
  22. place4.add("上海");
  23. place4.add("天津");
  24. HashSet<String> place5=new HashSet<>();
  25. place5.add("杭州");
  26. place5.add("大连");
  27. broad.put("K1",place1);
  28. broad.put("K2",place2);
  29. broad.put("K3",place3);
  30. broad.put("K4",place4);
  31. broad.put("K5",place5);
  32. //创建需要覆盖的城市集合
  33. HashSet<String> allAreas=new HashSet<>();
  34. allAreas.add("北京");
  35. allAreas.add("上海");
  36. allAreas.add("天津");
  37. allAreas.add("广州");
  38. allAreas.add("深圳");
  39. allAreas.add("成都");
  40. allAreas.add("杭州");
  41. allAreas.add("大连");
  42. //创建一个集合用于存储贪心算法每轮所选择的站点
  43. ArrayList<String> selects=new ArrayList<>();
  44. //创建一个临时集合,用于存储每个站点覆盖的城市
  45. HashSet<String> tempSet=new HashSet<>();
  46. //用于保存循环中的最优站点
  47. String maxKey=null;
  48. //用于保存循环中maxKey对应的站点与allAreas的交集大小
  49. int maxKeySize=0;
  50. while (allAreas.size()>0){//allAreas长度大于0,说明还有城市未必覆盖
  51. for (String key:broad.keySet()) {//应用贪心算法获取最优站点解
  52. tempSet.addAll(broad.get(key));//获取key站点对应的所有城市
  53. tempSet.retainAll(allAreas);//将tempSet的数据与allAreas数据求交集,并赋给tempSet
  54. //tempSet.size()>maxKeySize这句话就是贪心算法的应用
  55. if (tempSet.size()>0 && (maxKey==null || tempSet.size()>maxKeySize)){
  56. maxKey=key;
  57. maxKeySize=tempSet.size();//保存本次的交集大小,方便下一次循环产生的交集与之比较,找到最优站点
  58. }
  59. tempSet.clear();//清空,方便下次循环取值
  60. }
  61. if (maxKey!=null){//说明找到了本次循环的最优站点
  62. selects.add(maxKey);//将找到的最优站点加入到结果集合中
  63. allAreas.removeAll(broad.get(maxKey));//从未覆盖城市集合中删除maxKey对应站点的城市
  64. maxKey=null;//置空
  65. maxKeySize=0;//置零
  66. }
  67. }
  68. System.out.println("贪心算法筛选的解为="+selects);
  69. }
  70. }
贪心算法筛选的解为=[K1, K2, K3, K5]

 


其他常用算法,见下各链接

【常用十大算法_二分查找算法】

【常用十大算法_分治算法】

【常用十大算法_动态规划算法(DP)】

【常用十大算法_KMP算法】

【常用十大算法_普里姆(prim)算法,克鲁斯卡尔(Kruskal)算法】

【常用十大算法_迪杰斯特拉(Dijkstra)算法,弗洛伊德(Floyd)算法】

【常用十大算法_回溯算法】

 

【数据结构与算法整理总结目录 :>】<-- 宝藏在此(doge)  

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/822062
推荐阅读
相关标签
  

闽ICP备14008679号