一、贪心算法介绍

1.贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解

2.贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择

二、算法思路

1.贪心算法一般按照如下步骤进行:

  1. 建立数学模型来描述问题

  2. 把求解的问题分成若干个子问题

  3. 对每个子问题求解,得到子问题的局部最优解

  4. 把子问题的解局部最优解合成原来解问题的一个解

结论:贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。贪心算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,省去了为找最优解要穷尽所有可能而必须耗费的大量时间。贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解。虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪心算法不要回溯。

三、算法特性

1.有一个以最优方式来解决的问题。为了构造问题的解决方案,有一个候选的对象的集合:比如不同面值的硬币

2.随着算法的进行,将积累起其他两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已经被考虑过但被丢弃的候选对象。

3.有一个函数来检查一个候选对象的集合是否提供了问题的解答,该函数不考虑此时的问题解决方法是否最优。

4.还有一个函数来检查是否一个候选对象的集合是可行的,即是否可能往集合上添加更多的候选对象以获得一个解。和上一个函数一样,此时不考虑解决方法的最优性。

5.选择函数可以指出哪一个剩余的候选对象最有希望构成问题的解。

6.最后,目标函数给出解的值。

四、贪心算法的最佳应用–集合覆盖

  1. 假设存在如下表的需要付费的广播台,以及广播台信号可以覆盖的地区。 如何选择最少的广播台,让所有 的地区都可以接收到信号。

  1. 如何找出覆盖所有地区的广播台的集合呢,使用穷举法实现,列出每个可能的广播台的集合,这被称为幂集。假 设总的有 n 个广播台,则广播台的组合总共有 2ⁿ -1 个,假设每秒可以计算 10 个子集, 如图:

综合考虑使用贪心算法,效率高

  1. 目前并没有算法可以快速计算得到准备的值, 使用贪心算法,则可以得到非常接近的解,并且效率高。选择 策略上,因为需要覆盖全部地区的最小集合:

  2. 遍历所有的广播电台, 找到一个覆盖了最多未覆盖的地区的电台(此电台可能包含一些已覆盖的地区,但没有关 系)

  3. 将这个电台加入到一个集合中(比如 ArrayList), 想办法把该电台覆盖的地区在下次比较时去掉。

  4. 重复第 1 步直到覆盖了全部的地区

五、代码实现

package cn.zzw.algorithm.greedy;import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;public class GreedyAlgorithm {public static void main(String[] args) {//创建一个HashMap集合,将广播电台以及所覆盖的地址放入到HashMap中HashMap<String, HashSet<String>> broadcasts = new HashMap<String, HashSet<String>>();//将每一个电台覆盖的地区放入到broadcasts中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("大连");//将电台和电台所覆盖的地区全部放入到HashMap中broadcasts.put("K1",hashSet1);broadcasts.put("k2",hashSet2);broadcasts.put("k3",hashSet3);broadcasts.put("k4",hashSet4);broadcasts.put("k5",hashSet5);//存放所有的地区HashSet<String> allAreas=new HashSet<String>();allAreas.add("北京");allAreas.add("上海");allAreas.add("天津");allAreas.add("广州");allAreas.add("深圳");allAreas.add("成都");allAreas.add("杭州");allAreas.add("大连");//创建ArrayList集合,存放已经选择好的电台的集合ArrayList<String> selects=new ArrayList<String>();//定义一个临时的集合,存放遍历过程中电台覆盖的地区和当前还没有覆盖的地区的交集HashSet<String> tempSet=new HashSet<String>();//定义一个maxKey,保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的key//如果maxKey不为null,则会加入到selects中String maxKey=null;//如果allAreas不为0,则表示还没有覆盖到所有地区while (allAreas.size()!=0){int count=0;maxKey=null;//遍历broadcasts,取出对应的keyfor (String key:broadcasts.keySet()){//每进行一次for循环,需要对tempSet进行一次清空tempSet.clear();//获取当前key能够覆盖的地区HashSet<String> areas=broadcasts.get(key);tempSet.addAll(areas);//求出tempSet集合与allAreas集合的交集,并把交集部分赋值给tempSettempSet.retainAll(allAreas);//如果当前这个集合包含的未覆盖地区的数量,比maxKey指向的地区还多,就需要重置maxKey//tempSet.size()>broadcasts.get(maxKey).size()体现出贪心算法的核心if (tempSet.size()>0 && (maxKey==null || tempSet.size()>broadcasts.get(maxKey).size())){maxKey=key;}}if (maxKey!=null){//将maxKey加入到selects中selects.add(maxKey);System.out.println("每次加入到集合中的电台是:"+selects);//并且需要将maxKey所指向的集合所覆盖的地区从allAreas中去除allAreas.removeAll(broadcasts.get(maxKey));}}//!!!为什么这里输出不了最终的电台System.out.println("最终的电台是:"+selects);}}

六、测试结果

"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=52382:D:\IntelliJ IDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\1\IdeaProjects\algorithm\out\production\algorithm" cn.zzw.algorithm.greedy.GreedyAlgorithm
每次加入到集合中的电台是:[K1]
每次加入到集合中的电台是:[K1, k2]
每次加入到集合中的电台是:[K1, k2, k3]
每次加入到集合中的电台是:[K1, k2, k3, k5]

七、贪心算法的使用条件

1.贪心选择性质

一个问题的整体最优解可通过一系列局部的最优解的选择达到,并且每次的选择可以依赖以前作出的选择,但不依赖于后面要作出的选择,这就是贪心选择性质。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所做的贪心选择最终导致的整体最优解。

2.最优子结构性质

当一个问题的最优解包含其子问题的最优解时,此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心算法求解的关键所在。在实际应用中,至于什么问题具有什么样的贪心选择性质是不确定的,需要具体问题具体分析。

七、解题策略

贪心算法不从整体最优上加以考虑,所做出的仅是在某种意义上的局部最优选择。使用贪心策略要注意局部最优与全局最优的关系,选择当前的局部最优并不一定能推导出问题的全局最优。贪心策略解题需要解决以下两个问题:

1、该问题是否适合使用贪心策略求解,也就是该问题是否具有贪心选择性质 ;

2、制定贪心策略,以达到问题的最优解或较优解 。

要确定一个问题是否适合用贪心算法求解,必须证明每一步所作的贪心选择最终导致问题的整体最优解。证明的大致过程为:首先考察问题的一个整体最优解,并证明可修改这个最优解,使其以贪心选择开始,做了贪心选择后,原问题简化为规模更小的类似子问题。然后用数学归纳法证明通过每一步做贪心选择,最终可得到问题的整体最优解。

三十六、贪心算法--集合覆盖问题相关推荐

  1. 三十六、Java集合中的HashMap

    @Author:Runsen @Date:2020/6/3 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘课严重,专业排名 ...

  2. 算法 - 贪心算法(集合覆盖问题求解)

    1.穷举法 2.贪心算法 遍历集合的key,用当前key的value和allAreas去取交集),然后和(maxKey和allAreas的交集)比较大小,如果当前key的结合size大就把当前key赋 ...

  3. 推荐系统三十六式——学习笔记(三)

    由于工作需要,开始学习推荐算法,参考[极客时间]->[刑无刀大牛]的[推荐系统三十六式],学习并整理. 3 原理篇之紧邻推荐 3.1 协同过滤 要说提到推荐系统中,什么算法最名满天下,我想一定是 ...

  4. 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索

    第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果. 时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微 ...

  5. OpenCV学习笔记(三十六)——Kalman滤波做运动目标跟踪 OpenCV学习笔记(三十七)——实用函数、系统函数、宏core OpenCV学习笔记(三十八)——显示当前FPS OpenC

    OpenCV学习笔记(三十六)--Kalman滤波做运动目标跟踪 kalman滤波大家都很熟悉,其基本思想就是先不考虑输入信号和观测噪声的影响,得到状态变量和输出信号的估计值,再用输出信号的估计误差加 ...

  6. 三十六進制之間隨便轉換

    去年在網上給一家公司投簡歷的時候,對方要求寫一個任意進制轉換的函數,當時沒有回過神來,也不知道JAVA中有這樣的函數,呵呵.于是就自己操刀,寫了這個三十六進制之音隨便轉的函數.不過,權當練習吧,如果你 ...

  7. 实例三十六:精确除法计算(*)

    实例三十六:精确除法计算 问题描述: 使用数组精确计算 M/N(0<M<N<100)的值.如果 M/N 是无限循环小数,则计算输出它的第一个循环节,并输出循环节的起止位置. The ...

  8. 实验三十六 Windows Server 2012 RDS桌面虚拟化之七VDI虚拟桌面的更新和维护

    实验三十六 Windows Server 2012 RDS桌面虚拟化之七VDI虚拟桌面的更新和维护 在远程桌面服务中,往往需要定期对虚拟桌面更新补丁或应用程序,以往的方法是一台一台的更新:但是在Win ...

  9. [Python从零到壹] 三十六.图像处理基础篇之图像算术与逻辑运算详解

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

最新文章

  1. 解决Intellij idea运行android application时找不到aapt/li...
  2. php curl基本操作
  3. 程序员职业生涯全攻略,附神级跳槽攻略图
  4. 论基于candence的组装清单做法
  5. ArcIMS9.0 学习
  6. 解释Spring中IOC, DI, AOP
  7. Django下的templates 和 static静态文件
  8. (OK) Linux epoll模型—socket epoll server client chat
  9. Cadence Orcad Capture原理图导出PDF图文视频教程
  10. 无线桥接dhcp服务器关闭吗,光猫桥接要关闭dhcp吗
  11. 使用 docker 来安装 oracle 11c
  12. EasyCHM chm文件制作过程及软件附软件下载地址
  13. 基于改进SSIM算法的图像清晰度识别
  14. 托业考试心得(930分;人大教材;6级500分水平,20天复习)
  15. 华硕服务器系统安装系统安装教程视频,华硕的系统安装教程 华硕u盘安装系统教程...
  16. 2023北京眼镜展览会暨首届智能眼镜展览会
  17. 注册CSDN七年才发布第一篇博文是什么感觉
  18. Excel根据手机号区分运营商
  19. Xilinx SDx尝鲜之下载安装
  20. easypoi利用模板导出图片到Excel;解决easypoi导出图片到合并单元格单元格被拉伸的问题

热门文章

  1. antd Form 表单验证
  2. React 项目---class 创建组件 (11)
  3. opencv文件路径问题
  4. Drug Target Review | 虚拟现实(VR)用于新药设计
  5. Tensorflow |(1)初识Tensorflow
  6. NLP(3)| seq to seq 模型
  7. 第六课.模型评估与模型选择
  8. ​JGG | TaxonKit:一款实用又高效的NCBI分类学数据工具包
  9. 是什么限制了我对Graphical abstract的想象力
  10. 研究生,导师不是你的保姆……