贪心算法

青旅半醒 2022-11-13 05:29 260阅读 0赞

一:贪心算法介绍

  1. 贪婪算法(贪心算法)是指在对问题进行求解时,在每一步选择中都采取最好或者最优**(即最有利)**的选择,从而希望能够导致结果是最好或者最优的算法。
  2. 贪婪算法所得到的结果不一定是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果。

二:应用场景-集合覆盖问题

假设存在下面需要付费的广播台,以及广播台信号可以覆盖的地区。 如何选择最少的广播台,让所有的地区都可以接收到信号。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NDY5MDU1_size_16_color_FFFFFF_t_70

使用贪婪算法,效率高 :

  1. 1) 目前并没有算法可以快速计算得到准备的值,使用贪婪算法,则可以得到非常接近的解,并且效率高。选择策略上,因为需要覆盖全部地区的最小集合
  2. 2) 遍历所有的广播电台, 找到一个覆盖了最多未覆盖的地区的电台(此电台可能包含一些已覆盖的地区,但没有关系)
  3. 3) 将这个电台加入到一个集合中(比如 ArrayList), 想办法把该电台覆盖的地区在下次比较时去掉。
  4. 4) 重复第1步直到覆盖了全部的地区

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NDY5MDU1_size_16_color_FFFFFF_t_70 1

代码实现:

  1. package com.github.greedy;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.HashSet;
  5. /**
  6. * @author lizhangyu
  7. * @version 1.0
  8. * @description
  9. * @date 2021/3/29 15:06
  10. */
  11. public class GreedyAlgorithm {
  12. public static void main(String[] args) {
  13. //创建广播电台,放入到Map
  14. HashMap<String, HashSet<String>> broadcasts = new HashMap<String, HashSet<String>>();
  15. HashSet<String> hashSet1 = new HashSet<>();
  16. hashSet1.add("北京");
  17. hashSet1.add("上海");
  18. hashSet1.add("天津");
  19. HashSet<String> hashSet2 = new HashSet<>();
  20. hashSet2.add("广州");
  21. hashSet2.add("北京");
  22. hashSet2.add("深圳");
  23. HashSet<String> hashSet3 = new HashSet<>();
  24. hashSet3.add("成都");
  25. hashSet3.add("上海");
  26. hashSet3.add("杭州");
  27. HashSet<String> hashSet4 = new HashSet<>();
  28. hashSet4.add("上海");
  29. hashSet4.add("天津");
  30. HashSet<String> hashSet5 = new HashSet<>();
  31. hashSet5.add("杭州");
  32. hashSet5.add("大连");
  33. //加入到map
  34. broadcasts.put("K1", hashSet1);
  35. broadcasts.put("K2", hashSet2);
  36. broadcasts.put("K3", hashSet3);
  37. broadcasts.put("K4", hashSet4);
  38. broadcasts.put("K5", hashSet5);
  39. //allAreas 存放所有需要覆盖的地区
  40. HashSet<String> allAreas = new HashSet<>();
  41. allAreas.add("北京");
  42. allAreas.add("上海");
  43. allAreas.add("天津");
  44. allAreas.add("广州");
  45. allAreas.add("深圳");
  46. allAreas.add("成都");
  47. allAreas.add("杭州");
  48. allAreas.add("大连");
  49. //创建ArrayList,存放选择的电台集合
  50. ArrayList<String> selects = new ArrayList<>();
  51. //定义一个临时的集合,在遍历的过程中,存放遍历过程中的电台覆盖的地区和当前还没有覆盖的地区的交集
  52. HashSet<String> tempSet = new HashSet<String>();
  53. //定义maxKey,保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的 key
  54. //如果maxKey不为null,则会加入到selects
  55. String maxKey = null;
  56. //如果allAreas不为0,则表示还没有覆盖到所有的地区
  57. while (allAreas.size() != 0) {
  58. //每进行一次 while,需要
  59. maxKey = null;
  60. for (String key : broadcasts.keySet()) {
  61. //每进行一次 for
  62. tempSet.clear();
  63. //当前这个 key 能够覆盖的地区
  64. HashSet<String> areas = broadcasts.get(key);
  65. tempSet.addAll(areas);
  66. //求出tempSet和allAreas集合的交集, 交集会赋给tempSet
  67. tempSet.retainAll(allAreas);
  68. //如果当前这个集合包含的未覆盖地区的数量,比 maxKey 指向的集合地区还多
  69. // 就需要重置 maxKey
  70. // tempSet.size() >broadcasts.get(maxKey).size()) 体现出贪心算法的特点,每次都选择最优的
  71. if (tempSet.size() > 0 && (maxKey == null || tempSet.size() > broadcasts.get(maxKey).size())) {
  72. maxKey = key;
  73. }
  74. }
  75. if (maxKey != null) {
  76. //maxKey != null, 就应该将 maxKey 加入 selects
  77. selects.add(maxKey);
  78. //将 maxKey 指向的广播电台覆盖的地区,从 allAreas 去掉
  79. allAreas.removeAll(broadcasts.get(maxKey));
  80. }
  81. }
  82. System.out.println("得到的选择结果是" + selects);//[K1,K2,K3,K5]
  83. }
  84. }

运行结果:

  1. 得到的选择结果是[K1, K2, K3, K5]

贪心算法注意事项和细节

1) 贪婪算法所得到的结果不一定是最优的结果( 有时候会是最优解 ) ,但是都是相对近似 ( 接近 ) 最优解的结果。

2) 比如上题的算法选出的是 K1, K2, K3, K5 ,符合覆盖了全部的地区。

3) 但是我们发现 K2, K3,K4,K5 也可以覆盖全部地区,如果 K2 的使用成本低于 K1, 那么我们上题的 K1, K2, K3, K5 虽然是满足条件,但是并不是最优的。

发表评论

表情:
评论列表 (有 0 条评论,260人围观)

还没有评论,来说两句吧...

相关阅读

    相关 贪心算法

    贪心算法也称贪婪算法,其核心思想就是:每步都采用最优的做法。        贪心算法所得到的结果往往不是最优的结果(有时候是最优解),但都是相对接近最优解的。       

    相关 贪心算法

    一:贪心算法介绍 1. 贪婪算法(贪心算法)是指在对问题进行求解时,在每一步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的算法。 2.

    相关 贪心算法

    贪心算法的基本要素 对于一个具体的问题,怎么知道是否可用贪心算法解此问题,以及能否得到问题的最优解呢?这个问题很难给予肯定的回答。 但是,从许多可以用贪心算法求解的问题

    相关 贪心算法

    贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,所做出的是在某种意义上的局部最优解。举一个简单的贪心法例子,平时

    相关 贪心算法

    1.钞票支付问题,1元,2元,5元,10元,20元,50元,100元钞票无穷张,使用这些钞票怎么支付,最少需要多少张。 思路:尽可能使用面额较大的金额数目。反证法:若不成立,

    相关 贪心算法

    一、什么是贪心算法 贪心算法,又称贪婪算法(Greedy Algorithm),是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优解出发来考虑,它

    相关 贪心算法

    一 问题提出 集合覆盖问题 假设存在下面需要付费的广播台,以及广播台信号可以覆盖的地区。 如何选择最少的广播台,让所有的地区都可以接收到信号。 ![watermark