目录
1. 贪心算法介绍
算法可以贪心,人不能贪心哦~
- 贪婪算法(贪心算法)是指在对问题进行求解时,在每一步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的算法
- 贪婪算法所得到的结果不一定 是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果
2. 应用场景—集合覆盖问题
2.1 思路分析
➢ 如何找出覆盖所有地区的广播台的集合呢,使用穷举法实现,列出每个可能的广播台的集合,这被称为幂集。假设总的有n个广播台,则广播台的组合总共有2n -1个,假设每秒可以计算10个子集,如图:
➢ 使用贪婪算法,效率高:目前并没有算法可以快速计算得到准备的值,使用贪婪算法,则可以得到非常接近的解,并且效率高。选择策略上,因为需要覆盖全部地区的最小集合:
- 遍历所有的广播电台,找到一个覆盖了最多未覆盖的地区的电台(此电台可能包含一些己覆盖的地区,但没有关系)
- 将这个电台加入到一个集合中(比如ArrayList),想办法把该电台覆盖的地区在下次比较时去掉。
- 重复第1步直到覆盖了全部的地区
3. 代码
package com.example.datastructureandalgorithm.greedy;
import java.util.*;
/**
* @author 浪子傑
* @version 1.0
* @date 2020/6/15
*/
public class GreedyDemo {
public static void main(String[] args) {
// 创建电台,放入map
Map<String, Set<String>> broadcasts = new HashMap<String, Set<String>>();
Set set1 = new HashSet<String>();
set1.add("北京");
set1.add("上海");
set1.add("天津");
Set set2 = new HashSet<String>();
set2.add("广州");
set2.add("北京");
set2.add("深圳");
Set set3 = new HashSet<String>();
set3.add("成都");
set3.add("上海");
set3.add("杭州");
Set set4 = new HashSet<String>();
set4.add("上海");
set4.add("天津");
Set set5 = new HashSet<String>();
set5.add("杭州");
set5.add("大连");
broadcasts.put("K1", set1);
broadcasts.put("K2", set2);
broadcasts.put("K3", set3);
broadcasts.put("K4", set4);
broadcasts.put("K5", set5);
// 存放所有的地区
Set allAreas = new HashSet<String>();
allAreas.add("北京");
allAreas.add("上海");
allAreas.add("杭州");
allAreas.add("天津");
allAreas.add("成都");
allAreas.add("大连");
allAreas.add("广州");
allAreas.add("深圳");
// 存放选择的电台
List selects = new ArrayList<String>();
// 循环,直到allAreas大小为0
while (allAreas.size() != 0) {
// 中间变量,存放选择的最大的电台key
String maxKey = null;
// 循环所有的电台
for (String key : broadcasts.keySet()) {
// 中间变量,用来存放当前key和allAreas的交集
Set<String> tempSet = new HashSet<>();
// 获取key对应的所有地区
Set<String> areas = broadcasts.get(key);
// 将当前key的地区放入中间变量
tempSet.addAll(areas);
// 求出当前key和allAreas的交集
tempSet.retainAll(allAreas);
// 如果交集不为空,并且
// 最大电台的maxKey为空或者交集大于maxKey对应的地区的时候
// 需要重置maxKey
if (tempSet.size() > 0 &&
(maxKey == null || tempSet.size() > broadcasts.get(maxKey).size())) {
maxKey = key;
}
}
if (maxKey != null) {
selects.add(maxKey);
allAreas.removeAll(broadcasts.get(maxKey));
}
}
System.out.println(selects);
}
}