贪心算法

贪心算法

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

贪心算法的设计思想

         贪心算法在解决这个问题的策略上目光短浅,仅仅依据当前已有的信息就做出选择,并且一旦做出了选择,无论将来有什么结果,这个选择都不会改变。换言之,贪心法并非从总体最优考虑,它所做出的选择仅仅是在某种意义上的局部最优。贪心算法对于大部分的优化问题都能产生最优解,但不能总获得总体最优解,通常能够获得近似最优解。

引例 [找零钱]

一个小孩买了价值少于1美元的糖,并将1美元的钱交给售货员。售货员希望用数目最少的硬币找给小孩。如果提供了数目不限的面值为2 5美分、1 0美分、5美分、及1美分的硬币。售货员分步骤组成要找的零钱数,每次添�一个硬币。选择硬币时所採用的贪婪准则例如以下:每一次选择应使零钱数尽量增大。为保证解法的可行性(即:所给的零钱等于要找的零钱数),所选择的硬币不应使零钱总数超过终于所需的数目

引例分析

为使找回的零钱的硬币数最小,不考虑找零钱的全部各种方案,而是从最大面值的币种開始,按递减的顺序考虑各币种,先尽量用大面值的币种,仅仅当不足大面值币种的金额才会去考虑下一种较小面值的币种。这就是在採用贪婪法。这样的方法在这里之所以总是最优,是由于银行对其发行的硬币种类和硬币面值的巧妙安排。假设仅仅有面值分别为1,5和11单位的硬币,而希望找回总额为15单位的硬币,按贪婪算法,应找1个11单位面值的硬币和4个1单位面值的硬币,共找回5个硬币。但最优的解答应是3个5单位面值的硬币。

贪心法的求解过程 

           用贪心法求解问题应该考虑例如以下几个方面:
(1)候选集合C:为了构造问题的解决方式,有一个候选集合C作为问题的可能解,即问题的终于解均取自于候选集合C。比如,在付款问题中,各种            面值的货币构成候选集合。
(2)解集合S:随着贪心选择的进行,解集合S不断扩展,直到构成一个满足问题的完整解。比如,在付款问题中,已付出的货币构成解集合。
(3)解决函数solution:检查解集合S是否构成问题的完整解。比如,在付款问题中,解决函数是已付出的货币金额恰好等于应付款。
(4)选择函数select:即贪心策略,这是贪心法的关键,它指出哪个候选对象最有希望构成问题的解,选择函数通常和目标函数有关。比如,在付款             问题中,贪心策略就是在候选集合中选择面值最大的货币。
(5)可行函数feasible:检查解集合中添�一个候选对象是否可行,即解集合扩展后是否满足约束条件。比如,在付款问题中,可行函数是每一步选              择的货币和已付出的货币相加不超过应付款。

贪心法的一般流程

Greedy(C)  //C是问题的输入集合即候选集合
{
    S={ };  //初始解集合为空集
    while (not solution(S))  //集合S没有构成问题的一个解
    {
       x=select(C);    //在候选集合C中做贪心选择
       if feasible(S, x)  //推断集合S中添�x后的解是否可行
          S=S+{x};
          C=C-{x};
    }
   return S;

贪心法的基本要素

      对于一个详细的问题,怎么知道是否可用贪心算法解此问题,以及是否能得到问题的最优解呢?这个问题非常难给予肯定的回答。
      可是,从很多能够用贪心算法求解的问题中看到这类问题一般具有2个重要的性质:
贪心选择性质
最优子结构性质
子问题:如果为了解决某一优化问题,须要依次作出n个决策D1,D2,…,Dn,对于不论什么一个整数k,1 < k < n,以Dk作为问题的初始状态,来进行以后的决策,这种问题就成为是原问题的一个子问题。

1.贪心选择性质

      所谓
贪心选择性质是指所求问题的
总体最优解能够通过一系列
局部最优的选择,换句话说,当考虑做何种选择的时候,我们仅仅考虑对当前问题最佳的选择而不考虑子问题的结果。这是贪心算法可行的第一个基本要素。
贪心算法以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。
      对于一个详细问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择终于导致问题的总体最优解。

2.最优子结构性质

       当一个问题的最优解包括其子问题的最优解时,称此问题具有
最优子结构性质。问题的最优子结构性质是该问题可用贪心算法求解的关键特征。

贪心法的应用

  • 哈夫曼编码
  • 0-1背包问题
  • 磁盘文件的存储
  • 生产调度问题
  • 信息查询


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/118543.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • java—常量「建议收藏」

    java—常量「建议收藏」常量:在程序执行的过程中其值不可以发生改变。 1.java中常量分类:    A:字面值常量     字符串常量   用双引号括起来的内容      举例:"lixiaochi","liyan"     整数常量      所有整数      举例:12,23     小数常量      所有小数   …

  • pycharm如何全局进行查找一个关键词

    pycharm如何全局进行查找一个关键词PyCharm的FindinPath功能提供了全局查找功能,快捷键为Ctrl+Shift+F。Find则是在当前文件查找,快捷键为Ctrl+F。这两个个功能非常实用。FindinPath的使用:按快捷键Ctrl+Shift+F或从从菜单Edit-》Find-》FindinPath进入全局查找界面。如下图所示,在Texttofind输入要查找的内…

  • kill命令详解_linux杀死进程kill

    kill命令详解_linux杀死进程kill大多数人对kill命令的理解就是杀死一个进程,而这仅仅是kill的一个功能。Kill的zhenshkill用途是向一个进程发送信号,而杀死一个进程仅仅是其中的一个功能。

    2022年10月25日
  • 使用jks文件为apk签名

    使用jks文件为apk签名参与的项目近期要求安全检测,apk不达标并且无法修复的话会要求使用官方加固包。加固之后的包签名会失效,所有需要重新进行签名。今天借此机会记录一下整个操作流程。原来apk是使用jks格式的签名文件来操作的,还有一种是keystore文件格式。我们先来看jks文件格式怎么操作一、jks格式操作步骤:1、基本语法jarsigner-digestalgSHA1-sigalgSHA1withRSA-verbose-keystore{签名文件}-storepass{签名密码}-signe.

  • css固定定位_css定位布局

    css固定定位_css定位布局html>htmllang=”en”>head>metacharset=”UTF-8″>title>css固定定位title>style>#back{width:100px;height:100px;background-color:#FF6500;

    2022年10月22日
  • mybatis拦截器不生效_自动助力器失效是什么原因

    mybatis拦截器不生效_自动助力器失效是什么原因现象:自定义插件注册成功,但是始终不进入拦截器方法;排查Mybatis拦截器是采用的责任链模式,一般拦截器中intercept方法中最后执行invocation.proceed()方法,将拦截器责任链向后传递;但是查看pageHelper源码可以发现,他的拦截器方法中并没有向后传递责任链,而是直接执行了查询:com.github.pagehelper.PageInterceptor#intercept思路想办法让自定义拦截器,在pageHelper拦截器之前执行;所以需要使自定义拦

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号