贪心算法解决集合覆盖问题
问题描述:
假设存在下面需要付费的广播台,以及广播台需要覆盖的地区,如何选择最少的广播台,让所有的地区都可以接受到信号.
广播台 | 覆盖地区 |
---|---|
k1 | “北京”,“上海,“天津”” |
k2 | “广州”,“北京,“深圳”” |
k3 | “成都”,“上海,“杭州”” |
k4 | “上海,“天津”” |
k5 | “杭州”,“大连”” |
k6 | “福州”,“重庆”” |
贪心算法:
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
解决思路:
1.添加覆盖地区,并构建广播站
HashSet<String> hashSet1 = new HashSet<>();
hashSet1.add("北京");
hashSet1.add("上海");
hashSet1.add("天津");
HashSet<String> hashSet2 = new HashSet<>();
hashSet2.add("北京");
hashSet2.add("广州");
hashSet2.add("深圳");
HashSet<String> hashSet3 = new HashSet<>();
hashSet3.add("成都");
hashSet3.add("上海");
hashSet3.add("杭州");
HashSet<String> hashSet4 = new HashSet<>();
hashSet4.add("上海");
hashSet4.add("天津");
HashSet<String> hashSet5 = new HashSet<>();
hashSet5.add("杭州");
hashSet5.add("大连");
HashSet<String> hashSet6 = new HashSet<>();
hashSet6.add("福州");
hashSet6.add("重庆");
//构建广播台
HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
broadcasts.put("k1", hashSet1);
broadcasts.put("k2", hashSet2);
broadcasts.put("k3", hashSet3);
broadcasts.put("k4", hashSet4);
broadcasts.put("k5", hashSet5);
broadcasts.put("k6", hashSet6);
`
2.构建存放所有需要覆盖的地区的集合,每添加一个广播站就要从该集合中清除对应的地区;
//存放所有需要覆盖的地区
HashSet<String> allAreas = new HashSet<>();
for (Set<String> areas : broadcasts.values()) {
//只能addAll,add会出现[“北京”,“上海,“天津””][“广州”,“北京,“深圳””]按照集合的形式存在会有重复
allAreas.addAll(areas);
}
3.遍历广播站每次找出能覆盖待覆盖区域数最多的广播站,这一步就是贪心算法的体现,局部最优
完整java代码实现:
package com.yg.algorithm;/*
@author Mu_Mu
@date 2020/3/19 10:15
*/
import java.util.*;
public class GreedyAlogorithm {
public static void main(String[] args) {
//添加覆盖地区
HashSet<String> hashSet1 = new HashSet<>();
hashSet1.add("北京");
hashSet1.add("上海");
hashSet1.add("天津");
HashSet<String> hashSet2 = new HashSet<>();
hashSet2.add("北京");
hashSet2.add("广州");
hashSet2.add("深圳");
HashSet<String> hashSet3 = new HashSet<>();
hashSet3.add("成都");
hashSet3.add("上海");
hashSet3.add("杭州");
HashSet<String> hashSet4 = new HashSet<>();
hashSet4.add("上海");
hashSet4.add("天津");
HashSet<String> hashSet5 = new HashSet<>();
hashSet5.add("杭州");
hashSet5.add("大连");
HashSet<String> hashSet6 = new HashSet<>();
hashSet6.add("福州");
hashSet6.add("重庆");
//构建广播台
HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
broadcasts.put("k1", hashSet1);
broadcasts.put("k2", hashSet2);
broadcasts.put("k3", hashSet3);
broadcasts.put("k4", hashSet4);
broadcasts.put("k5", hashSet5);
broadcasts.put("k6", hashSet6);
//存放所有需要覆盖的地区
HashSet<String> allAreas = new HashSet<>();
for (Set<String> areas : broadcasts.values()) {
//只能addAll,add会出现[“北京”,“上海,“天津””][“广州”,“北京,“深圳””]按照集合的形式存在会有重复
allAreas.addAll(areas);
}
//存放需要选择的广播站列表
ArrayList<String> broadList = new ArrayList<>();
//maxKey代表能覆盖待覆盖区域最大的广播站
String maxKey = null;
int maxNum = 0;//能覆盖待覆盖区域最大的数量
//只要allAreas.size() >0说明还有地区需要被覆盖
//存放能覆盖待覆盖的区域
HashSet<String> tempSet = new HashSet<>();
while (allAreas.size() > 0) {
maxKey = null;
for (String key : broadcasts.keySet()) {
tempSet.clear();
tempSet.addAll(broadcasts.get(key));
tempSet.retainAll(allAreas);
if (tempSet.size() > 0 && (maxKey == null || tempSet.size() > maxNum)) {
maxKey = key;
maxNum = tempSet.size();
}
}
if (maxKey != null) {
broadList.add(maxKey);
//从待覆盖区域的集合中移除这次新增覆盖区域
allAreas.removeAll(broadcasts.get(maxKey));
}
}
System.out.println("待添加的广播站有:");
for (String str : broadList) {
System.out.print(str+" ");
}
}
}
还没有评论,来说两句吧...