算法导论学习笔记-第十六章-贪心算法

第十六章 贪心算法

 

总结:这一章通过活动选择问题引出贪心算法,讲了贪心策略的基本思想,并介绍了用了贪心策略的赫夫曼编码。

 

1.    贪心策略的基本思想

对有些最优化问题可以使用贪心算法来解决,贪心算法期望通过所做的局部最优选择来产生出一个全局最优解。但并不是所有最优化问题都可通过贪心算法来解决的。

贪心算法的步骤:

1)  将优化问题转化成这样的一个问题,即先做出选择,再解决剩下的一个子问题。

2)  证明原问题总是有有一个最优解是做贪心选择得到的,从而说明贪心选择的安全。

3)  说明在做出贪心选择后,剩余的子问题具有这样的一个性质。即如果将子问题的最优解和我们所做的贪心选择联合起来,可以得出原问题的一个最优解。

 

贪心选择性质:一个全局最优解可以通过局部最优(贪心)选择来达到。即当考虑做何选择时,我们只考虑对当前问题最佳的选择而不考虑子问题的结果。

 

使用贪心算法,必须做两个证明:

1)  证明每一步所做的贪心选择最终能产生一个全局最优解。在证明中先考察一个全局最优解,然后证明对该解加以修改,使其采用贪心选择,这个选择将原问题变为一个相似的、但更小的问题。

2)  假设原问题中做了一个贪心选择而得到了一个子问题。证明将此子问题的最优解与所做的贪心选择合并后,的确可以得到原问题的一个最优解。

 

贪心算法与动态规划:

在动态规划中,每一步都要做出选择,但是这些选择依赖于子问题的解。因此,动态规划一般是自底向上,从小子问题处理至大子问题。

在贪心算法中,我们所做的总是当前看似最佳的选择,然后再解决选择之后出现的子问题。贪心策略是自顶向下的,不断地将给定的问题实例规约为更小的问题。

 

2.    赫夫曼编码

前缀编码:没有一个编码是另一个编码的前缀。

HUFFMAN编码是最优前缀码的贪心算法,在每一步所有可能的合并中,选择一个代价最小的合并。

 

C是一个包含n个字符的集合,对C中的每个字符cf[c]代表c出现的频度。显然,对出现频度大的字符,对它的编码的长度应该尽可能小。

 

伪代码

HUFFMAN(C)

n <- |C|

Q <- C

for i <- 1 to n

      do allocate a new code z

           left[z] <- x <- EXTRACT-MIN(Q)

           right[z] <- y <- EXTRACT-MIN(Q)

           f[z] <- f[x]+f[y]

           INSERT(Q,z)

return EXTRACT-MIN(Q)

 

其中,Q是一个以f为关键字的最小优先级队列,可以用最小二叉堆实现。

复杂度分析:O(nlgn)

 

    原文作者:贪心算法
    原文地址: https://blog.csdn.net/kindlucy/article/details/5728989
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞