贪心算法解决集合覆盖问题

爱被打了一巴掌 2023-07-17 02:52 78阅读 0赞

问题描述:

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


































广播台 覆盖地区
k1 “北京”,“上海,“天津””
k2 “广州”,“北京,“深圳””
k3 “成都”,“上海,“杭州””
k4 “上海,“天津””
k5 “杭州”,“大连””
k6 “福州”,“重庆””

贪心算法:

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

解决思路:

1.添加覆盖地区,并构建广播站

  1. HashSet<String> hashSet1 = new HashSet<>();
  2. hashSet1.add("北京");
  3. hashSet1.add("上海");
  4. hashSet1.add("天津");
  5. HashSet<String> hashSet2 = new HashSet<>();
  6. hashSet2.add("北京");
  7. hashSet2.add("广州");
  8. hashSet2.add("深圳");
  9. HashSet<String> hashSet3 = new HashSet<>();
  10. hashSet3.add("成都");
  11. hashSet3.add("上海");
  12. hashSet3.add("杭州");
  13. HashSet<String> hashSet4 = new HashSet<>();
  14. hashSet4.add("上海");
  15. hashSet4.add("天津");
  16. HashSet<String> hashSet5 = new HashSet<>();
  17. hashSet5.add("杭州");
  18. hashSet5.add("大连");
  19. HashSet<String> hashSet6 = new HashSet<>();
  20. hashSet6.add("福州");
  21. hashSet6.add("重庆");
  22. //构建广播台
  23. HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
  24. broadcasts.put("k1", hashSet1);
  25. broadcasts.put("k2", hashSet2);
  26. broadcasts.put("k3", hashSet3);
  27. broadcasts.put("k4", hashSet4);
  28. broadcasts.put("k5", hashSet5);
  29. broadcasts.put("k6", hashSet6);

`

2.构建存放所有需要覆盖的地区的集合,每添加一个广播站就要从该集合中清除对应的地区;

  1. //存放所有需要覆盖的地区
  2. HashSet<String> allAreas = new HashSet<>();
  3. for (Set<String> areas : broadcasts.values()) {
  4. //只能addAll,add会出现[“北京”,“上海,“天津””][“广州”,“北京,“深圳””]按照集合的形式存在会有重复
  5. allAreas.addAll(areas);
  6. }

3.遍历广播站每次找出能覆盖待覆盖区域数最多的广播站,这一步就是贪心算法的体现,局部最优

完整java代码实现:

  1. package com.yg.algorithm;/*
  2. @author Mu_Mu
  3. @date 2020/3/19 10:15
  4. */
  5. import java.util.*;
  6. public class GreedyAlogorithm {
  7. public static void main(String[] args) {
  8. //添加覆盖地区
  9. HashSet<String> hashSet1 = new HashSet<>();
  10. hashSet1.add("北京");
  11. hashSet1.add("上海");
  12. hashSet1.add("天津");
  13. HashSet<String> hashSet2 = new HashSet<>();
  14. hashSet2.add("北京");
  15. hashSet2.add("广州");
  16. hashSet2.add("深圳");
  17. HashSet<String> hashSet3 = new HashSet<>();
  18. hashSet3.add("成都");
  19. hashSet3.add("上海");
  20. hashSet3.add("杭州");
  21. HashSet<String> hashSet4 = new HashSet<>();
  22. hashSet4.add("上海");
  23. hashSet4.add("天津");
  24. HashSet<String> hashSet5 = new HashSet<>();
  25. hashSet5.add("杭州");
  26. hashSet5.add("大连");
  27. HashSet<String> hashSet6 = new HashSet<>();
  28. hashSet6.add("福州");
  29. hashSet6.add("重庆");
  30. //构建广播台
  31. HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
  32. broadcasts.put("k1", hashSet1);
  33. broadcasts.put("k2", hashSet2);
  34. broadcasts.put("k3", hashSet3);
  35. broadcasts.put("k4", hashSet4);
  36. broadcasts.put("k5", hashSet5);
  37. broadcasts.put("k6", hashSet6);
  38. //存放所有需要覆盖的地区
  39. HashSet<String> allAreas = new HashSet<>();
  40. for (Set<String> areas : broadcasts.values()) {
  41. //只能addAll,add会出现[“北京”,“上海,“天津””][“广州”,“北京,“深圳””]按照集合的形式存在会有重复
  42. allAreas.addAll(areas);
  43. }
  44. //存放需要选择的广播站列表
  45. ArrayList<String> broadList = new ArrayList<>();
  46. //maxKey代表能覆盖待覆盖区域最大的广播站
  47. String maxKey = null;
  48. int maxNum = 0;//能覆盖待覆盖区域最大的数量
  49. //只要allAreas.size() >0说明还有地区需要被覆盖
  50. //存放能覆盖待覆盖的区域
  51. HashSet<String> tempSet = new HashSet<>();
  52. while (allAreas.size() > 0) {
  53. maxKey = null;
  54. for (String key : broadcasts.keySet()) {
  55. tempSet.clear();
  56. tempSet.addAll(broadcasts.get(key));
  57. tempSet.retainAll(allAreas);
  58. if (tempSet.size() > 0 && (maxKey == null || tempSet.size() > maxNum)) {
  59. maxKey = key;
  60. maxNum = tempSet.size();
  61. }
  62. }
  63. if (maxKey != null) {
  64. broadList.add(maxKey);
  65. //从待覆盖区域的集合中移除这次新增覆盖区域
  66. allAreas.removeAll(broadcasts.get(maxKey));
  67. }
  68. }
  69. System.out.println("待添加的广播站有:");
  70. for (String str : broadList) {
  71. System.out.print(str+" ");
  72. }
  73. }
  74. }

发表评论

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

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

相关阅读

    相关 贪心算法-广播台覆盖问题

    我们先看一个问题: 假设存在下面需要付费的广播台,以及广播台信号可以覆盖的地区。 如何选择最少的广播台,让所有的地区都可以接收到信号 ![在这里插入图片描述][wate

    相关 区间覆盖贪心

    题目描述 给定N个闭区间\[ai,bi\]以及一个线段区间\[s,t\],请你选择尽量少的区间,将指定线段区间完全覆盖。 输出最少区间数,如果无法完全覆盖则输出-1。