算法-贪心算法-集合覆盖问题

应用场景:

有5个广播台K1,K2,K3,K4,K5每个广播台都有限定的播放地区,如图:

广播台播放地区
K1北京、上海、天津
K2广州、北京、深圳
K3成都、上海、杭州
K4上海、天津
K5杭州、大连

问题:如何选取数量最少的广播台,覆盖北京、上海、天津、广州、深圳、成都、杭州、大连这8个城市?

贪心算法:

  1. HashSet存放未覆盖城市,北京、上海、天津、广州、深圳、成都、杭州、大连
  2. 遍历广播台找出含未覆盖城市最多的广播台
  3. 添加到答案中,并在未覆盖城市HashSet中移除该广播台所覆盖的城市
  4. 重复步骤2,直到未覆盖城市为0

贪心算法思想:每一次得到的解都是最优的

代码:

public class GreedyAlgorithm {
    public static void main(String[] args) {
        //广播台
        Set<String> k1 = new HashSet<>();
        k1.add("北京");
        k1.add("上海");
        k1.add("天津");
        Set<String> k2 = new HashSet<>();
        k2.add("广州");
        k2.add("北京");
        k2.add("深圳");
        Set<String> k3 = new HashSet<>();
        k3.add("成都");
        k3.add("上海");
        k3.add("杭州");
        Set<String> k4 = new HashSet<>();
        k4.add("上海");
        k4.add("天津");
        Set<String> k5 = new HashSet<>();
        k5.add("杭州");
        k5.add("大连");

        //存放广播电台的信息,以及对应的覆盖地区
        Map<String, Set<String>> broadcasts = new HashMap<>();
        broadcasts.put("K1",k1);
        broadcasts.put("K2",k2);
        broadcasts.put("K3",k3);
        broadcasts.put("K4",k4);
        broadcasts.put("K5",k5);

        //所有想覆盖的地区
        Set<String> allAreas = new HashSet<>();
        allAreas.add("北京");
        allAreas.add("上海");
        allAreas.add("天津");
        allAreas.add("广州");
        allAreas.add("深圳");
        allAreas.add("成都");
        allAreas.add("杭州");
        allAreas.add("大连");

        //存放所选的广播台
        List<String> selects = new ArrayList<>();
        //临时集合,来存放一个广播台含未覆盖的地区
        Set<String> tempSet = new HashSet<>();
        String maxKey = null;
        int maxTempSetSize = 0;
        while (allAreas.size() != 0){
            maxKey = null;
            maxTempSetSize = 0;
            //遍历广播台,找出含未覆盖地区最多的广播台
            for(String broadcast : broadcasts.keySet() ){
                tempSet.clear();
                Set<String> areas = broadcasts.get(broadcast);//获取该广播台所能覆盖到的范围
                tempSet.addAll(areas);
                tempSet.retainAll(allAreas);//用当前广播台能覆盖地区对所有未覆盖地区进行交集得出当前广播台含未覆盖的地区
                if ( tempSet.size()>0 && (maxKey==null || tempSet.size() > maxTempSetSize) ){
                    maxKey = broadcast;
                    maxTempSetSize = tempSet.size();
                }
            }
            if(maxKey!=null){
                selects.add(maxKey);
                allAreas.removeAll(broadcasts.get(maxKey));//移除 添加广播台 已覆盖的地区
            }
        }
        System.out.println(selects);
    }
}
 >>>
[K1, K2, K3, K5]

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值