贪心算法解决电台覆盖问题

这篇博客介绍了如何使用贪心算法解决电台覆盖问题。通过遍历所有电台,找到能覆盖最多未覆盖地区的电台,并将其加入选择电台的集合中,直至所有地区被覆盖。主要利用HashSet进行交集和并集操作,以确定最佳电台。代码示例展示了具体的实现过程。
摘要由CSDN通过智能技术生成

贪心算法解决电台问题:

贪心算法:局部最优退出全局最优,找不出明显的反例来否决这个假设

主要思路:

  • 1、遍历所有电台k1~Kn 找到一个能覆盖最多 还没覆盖地区 的电台
  • 2、将这个电台加入到一个集合中(如ArrayList,最后需要的电台结果就是放在这里面的),将该电台覆盖的地区在下次比较的时候去掉
  • 3、重复上述直到覆盖全部地区

主要使用HashSet:

  • 1、是因为Set集合元素不可重复,
  • 2、方法:tempSet.retainAll(allAreas);求交集并赋值给tempSet
  • 3、方法:tempSet.addAll(areas);直接把一个hashSet的全部元素添加到另外一个hasSet中
  • 4、方法: set1.removeAll(set2) 这个方法去研究一下,根据debug,删除的是两者(set1,set2)的交集

代码实现思路:

  • 1、创建hashMap存放广播电台,key就是电台名称,value就是电台能覆盖的地区(地区是个set集合)
  • 2、创建一个set : HashSet<String> allAreas 存放所有需要覆盖电台的地区(后来要对这些地区进行贪心算法分配)
  • 3、创建ArrayList<String> selects 放选择电台(最终结果)
  • 4、创建HashSet<String> tempSet 用于存放遍历过程中 电台覆盖的地区 和 当前还没有覆盖的地区的交集,它的size就可以用来判断下次遍历选哪个电台
  • 5、定义String maxKey , 保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的key(tempSet最大值对应的key)
  • 6、如果上面的maxKey != null,说明找到了目标电台,就可以放入到集合selects中去

7、主要代码:

while循环操作,只要allAreas 个数!=0,就继续做

7.1 求出maxKey:

7.1.1循环遍历map,获取所有的key,以及key(电台名称)对应的value(覆盖地区)
7.1.2把value放入tempSet中,之后与allArea取交集,并再存入tempSet中
7.1.3如果tempSet包含的未覆盖地区的数量,比maxKey指向的集合还多,重置MaxKey=地区遍历到的key
7.1.4这时候思考到,最外面的while循环,每次进行都要清空maxKey
7.1.5maxKey != null, 就应该将maxKey 加入selects

代码如下:

public class RadioStationGreedyAlgorithm {
    public static void main(String[] args) {
        greedyAlgorithm();
    }



    public static void greedyAlgorithm(){
        //1、创建hashMap存放广播电台,key就是电台名称,value就是电台能覆盖的地区(地区是个set集合)
        HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
        //对该hashMap进行初始化
        HashSet<String> hashSet1 = new HashSet<>();
        hashSet1.add("北京");
        hashSet1.add("上海");
        hashSet1.add("天津");

        HashSet<String> hashSet2 = new HashSet<String>();
        hashSet2.add("广州");
        hashSet2.add("北京");
        hashSet2.add("深圳");

        HashSet<String> hashSet3 = new HashSet<String>();
        hashSet3.add("成都");
        hashSet3.add("上海");
        hashSet3.add("杭州");


        HashSet<String> hashSet4 = new HashSet<String>();
        hashSet4.add("上海");
        hashSet4.add("天津");

        HashSet<String> hashSet5 = new HashSet<String>();
        hashSet5.add("杭州");
        hashSet5.add("大连");

        broadcasts.put("k1",hashSet1);
        broadcasts.put("k2",hashSet2);
        broadcasts.put("k3",hashSet3);
        broadcasts.put("k4",hashSet4);
        broadcasts.put("k5",hashSet5);

        //2、创建一个set: HashSet<String> allAreas 存放所有需要覆盖电台的地区(后来要对这些地区进行贪心算法分配)
        HashSet<String> allAreas = new HashSet<>();
        allAreas.add("北京");
        allAreas.add("上海");
        allAreas.add("天津");
        allAreas.add("广州");
        allAreas.add("深圳");
        allAreas.add("成都");
        allAreas.add("杭州");
        allAreas.add("大连");

        //3、创建ArrayList<String> selects 放选择电台(最终结果)
        ArrayList<String> selects = new ArrayList<>();
        //4、创建HashSet<String> tempSet 用于存放遍历过程中 电台覆盖的地区 和 当前还没有覆盖的地区的交集,它的size就可以用来判断下次遍历选哪个电台
        HashSet<String> tempSet = new HashSet<>();
        //5、定义String maxKey , 保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的key(tempSet最大值对应的key)
        //如果上面的maxKey != null,说明找到了目标电台,就可以放入到集合selects中去
        String maxKey = null;

        //7、主要代码:while循环操作,只要allAreas 个数!=0,就继续做
        while (allAreas.size() != 0){
            //每次下面for循环结束后是完成目前 allAreas 的最大maxKey的查找,查找完毕以后应该要删除allArea匹配好的地区,然后接着找
            //上面就说明了while循环的意义,那每次肯定都得清空maxKey
            maxKey = null;

            //求出maxKey
            for (Map.Entry<String,HashSet<String>> entry : broadcasts.entrySet()){
                String key = entry.getKey(); //每次遍历得到的电台名称k1~kn
                HashSet<String> value = entry.getValue(); //电台覆盖的地区
                //!!注意!一定记得清空tempSet
                tempSet.clear();

                tempSet.addAll(value);//把value的地区先全部给tempSet
                tempSet.retainAll(allAreas);//与allAreas取交集后将交集内容给tempSet,这样方便统计当前电台满足要求的个数
                if (tempSet.size() != 0 && (maxKey == null || tempSet.size() > broadcasts.get(maxKey).size())){
                    maxKey = key; //当前循环遍历到的key
                }
            }

            //每轮for循环结束后,完成一个当前allAreas最佳的电台匹配查找(一次就找到一个maxKey)
            //如果找到了这个maxKey,就应该统计到结果 select中去
            //这时候应该删除allArea中以及匹配好的地区,然后再进入while循环
            if (maxKey != null){
                selects.add(maxKey);
                //allAreas.removeAll(tempSet);
                // ??为什么这样就出错了?因为这里是是for循环,temSet对应的都是最后一个电台的,maxKey是最大的,取debug就知道了

                //allAreas.removeAll(broadcasts.get(maxKey));
                HashSet<String> set = new HashSet<>();
                set = broadcasts.get(maxKey);
                allAreas.removeAll(set);
            }
        }
        System.out.println("贪心算法求出的电台搭配:" + selects);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值