41-贪心算法
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了41-贪心算法,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3790字,纯文字阅读大概需要6分钟。
内容图文
1. 基本概念
- 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择,从而希望能够导致结果是最好或者最优的算法
- 也就是说,它不从整体最优上加以考虑,只顾眼前不顾大局,所以它所做出的也仅仅是在某种意义上的局部最优解
- 贪心算法不是对所有问题都能得到整体最好的解决办法,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的状态不会影响以后的状态,只与当前状态有关
- 虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路径问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,但其最终结果也都是近似(接近)最优解
2. 基本思路
- 满足两个条件
- 贪心策略
- 贪心策略适用的前提:局部最优策略能导致产生全局最优解
- 步骤
- 建立数学模型来描述问题
- 把求解的问题分成若干个子问题
- 对每个子问题求解,得到子问题的局部最优解
- 把这些"局部最优解"叠起来,就"当作"整个问题的最优解
3. 贪心选择性质*
- 所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,换句话说,当考虑做何种选择的时候,我们只考虑对当前问题最佳的选择而不考虑子问题的结果。这是贪心算法可行的第一个基本要素
- 贪心算法以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题
- 对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解
- 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心算法求解的关键特征
4. 由4能看出贪心和DP的区别
a. 相同点
都是通过不停的解决子问题,来得到最终结果的
b. 不同点
- 解决问题的思路
- DP解决问题:自底向上
- 贪心解决问题:自顶向下
- "子问题" 的人品
- DP经分解得到子问题往往不是互相独立的 ( 即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解
- 子问题:"大家都是一条船上的人,谁也别那个谁"
- 贪心的子问题独立,人如其名,只顾眼前不顾大局,总是做出在当前子问题看来是最好的选择
- God:"主顾眼前,以后咋办?!"
- 当前子问题:"以后?关我啥事,那是下个子问题要解决的事~ 我只要我自己当前爽了就行"
- DP经分解得到子问题往往不是互相独立的 ( 即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解
- 最优解
- DP 在分析子问题的时候,会使用前面子问题的最优结果,并且前面子问题的最后结果不受后面的影响,最后一个子问题即最优解
- 贪心得到的结果不一定是最优解,它是把这些个"局部最优解"叠起来,"当作"整个问题的最优解
c. summary
- 贪心解决不了就用动态规划
- 一般贪心算法的时间复杂度为O(nlgn),动态规划为O(n^2)
- 能用贪心解决就不用动态规划
5. 案例:集合覆盖
5.1 思路分析
a. 穷举法
- 列出每个可能的广播台的集合,这被称为 "幂集"
- 假设总的有 n 个广播台,则广播台的组合总共有 2? - 1 个,假设每秒可以计算 10 个子集
b. 贪心算法
- 目前并没有算法可以快速计算得到准备的值, 使用贪婪算法,则可以得到非常接近的解,并且效率高
- 选择策略上,因为需要覆盖全部地区的最小集合
- 遍历所有的广播电台,找到一个覆盖了最多未覆盖的地区的电台 (此电台可能包含一些已覆盖的地区,但没有关系)
- 将这个电台加入到一个集合中 (比如ArrayList),想办法把该电台覆盖的地区在下次比较时去掉
- 重复第 1 步直到覆盖了全部的地区
5.2 代码实现
public class GreedyDemo {
// 创建广播电台, 放入Map
static HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
//allAreas 存放所有的地区
static HashSet<String> allAreas = new HashSet<String>();
// 创建ArrayList, 存放选择的电台
static ArrayList<String> selects = new ArrayList<>();
public static void main(String[] args) {
init();
overSet();
System.out.println(selects);
}
public static void overSet() {
// 一个临时集合, 用来存储当前电台与allAreas的交集地区
HashSet<String> tempSet = new HashSet<>();
// 用来保存覆盖最多未覆盖地区的电台名称
String maxKey = null;
while(allAreas.size() != 0) {
// 置空
maxKey = null;
// 遍历broadcasts, 找到本轮的maxKey
for(String key : broadcasts.keySet()) {
// 清空
tempSet.clear();
// 当前K所覆盖的地区
HashSet<String> areas = broadcasts.get(key);
tempSet.addAll(areas);
// tempSet = areas ∩ allAreas
tempSet.retainAll(allAreas);
// 如果当前key所包含的未覆盖地区数量比maxKey还多, 那当前key才应该是maxKey(Greedy)
if(tempSet.size() > 0 &&
(maxKey == null || tempSet.size() > broadcasts.get(maxKey).size()))
maxKey = key;
}
// 如果maxKey != null, 则会加入到selects里面
if(maxKey != null) {
selects.add(maxKey);
allAreas.removeAll(broadcasts.get(maxKey));
}
}
}
public static void init() {
allAreas.add("北京");
allAreas.add("上海");
allAreas.add("天津");
allAreas.add("广州");
allAreas.add("深圳");
allAreas.add("成都");
allAreas.add("杭州");
allAreas.add("大连");
HashSet<String> hashSet1 = new HashSet<String>();
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("大连");
//加入到map
broadcasts.put("K1", hashSet1);
broadcasts.put("K2", hashSet2);
broadcasts.put("K3", hashSet3);
broadcasts.put("K4", hashSet4);
broadcasts.put("K5", hashSet5);
}
}
5.3 注意事项和细节
- 贪婪算法所得到的结果不一定是最优的结果 (有时候会是最优解),但是都是相对近似(接近) 最优解的结果
- 比如上题的算法选出的是 {K1, K2, K3, K5},符合覆盖了全部的地区
- 但是我们发现 {K2, K3, K4, K5} 也可以覆盖全部地区,如果 K2 的使用成本低于 K1,那么我们上题的 {K1, K2, K3, K5} 虽然是满足条件,但是并不是最优的
原文:https://www.cnblogs.com/liujiaqi1101/p/12489858.html
内容总结
以上是互联网集市为您收集整理的41-贪心算法全部内容,希望文章能够帮你解决41-贪心算法所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。