贪心算法

转自https://www.cnblogs.com/gavanwanggw/p/7141358.htmlhtml

怎么理解

 

  贪心法在解决这个问题的策略上目光短浅,仅仅依据当前已有的信息就作出选择,而且一旦作出了选择。不管未来有什么结果,这个选择都不会改变。算法

 

  一句话:不求最优,仅仅求可行解。函数

 

 

怎样推断

 

    对于一个详细的问题,怎么知道是否可用贪心算法解此问题,以及是否能获得问题的最优解?code

  咱们可以依据贪心法的2个重要的性质去证实:贪心选择性质和最优子结构性质htm

  一、贪心选择

  什么叫贪心选择?从字义上就是贪心也就是目光短线。贪图眼前利益。在算法中就是仅仅依据当前已有的信息就作出选择,而且之后都不会改变此次选择。(这是和动态规划法的主要差异)  对象

  因此对于一个详细问题。要肯定它是否具备贪心选择性质,必须证实每作一步贪心选择是否终于致使问题的整体最优解。blog

  二、最优子结构

  当一个问题的最优解包括其子问题的最优解时,称此问题具备最优子结构性质。递归

  这个性质和动态规划法的同样,最优子结构性质是可用动态规划算法或贪心算法求解的关键特征。io

 

 

 

区分动态规划

 

   动态规划算法一般以自底向上的方式解各子问题,是递归过程。class

  贪心算法则一般以自顶向下的方式进行,以迭代的方式做出相继的贪心选择,每做一次贪心选择就将所求问题简化为规模更小的子问题。

 

  以二叉树遍历为例:

   贪心法是从上到下仅仅进行深度搜索。也就是说它从根节点一口气走到黑的,它的代价取决于子问题的数目,也就是树的高度,每次在当前问题的状态上做出的选择都是1。不进行广度搜索。因此终于它得出的解不必定是最优解。很是有多是近似最优解。

  而动态规划法在最优子结构的前提下,从树的叶子节点開始向上进行搜索,并且在每一步都依据叶子节点的当前问题的情况做出选择,从而做出最优决策。因此她的代价是子问题的个数和可选择的数目。它求出的解必定是最优解。

 

 

通常求解过程

 

  使用贪心法求解可以依据下面几个方面进行(终于也相应着每步代码的实现),以找零钱为例:

  一、候选集合(C)

    经过一个候选集合C做为问题的可能解。(终于解均取自于候选集合C)

    好比。在找零钱问题中,各类面值的货币构成候选集合。

 

  二、解集合(S)

    每完毕一次贪心选择,将一个解放入S。终于得到一个完整解S

  三、解决函数(solution)

    检查解集合S是否构成问题的完整解。

    好比,在找零钱问题中。解决函数是已付出的货币金额刚好等于应付款。

  四、选择函数(select)

    即贪心策略。这是贪心法的关键,选择出最有但愿构成问题的解的对象。

(这个选择函数一般和目标函数有关)

          好比,在找零钱问题中,贪心策略就是在候选集合中选择面值最大的货币。

  五、可行函数(feasible)

    检查解集合中增长一个候选对象是否可行。(增长下一个对象后是否是知足约束条件)

    好比。在找零钱问题中,可行函数是每一步选择的货币和已付出的货币相加不超过应付款。

       

 

 

C的实现:(通常试题就是在这个基础上加入详细的实现)

  

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;

}
相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息