贪心算法(greedy algorithms)

贪心算法(greedy algorithms)

作者:Bluemapleman([email protected])

麻烦不吝star和fork本博文对应的github上的技术博客项目吧!谢谢你们的支持!

知识无价,写作辛苦,欢迎转载,但请注明出处,谢谢!


文章目录

  • 贪心算法(greedy algorithms)
  • 引入
  • 问题
    • 活动选择(Activity Selection)
    • 哈夫曼编码(Huffman Codes)
    • 边匹配(Edge Matching)
    • 顶点包含(Vertex Cover)
  • 贪心算法找到全局最优解的要求
  • 01背包问题
  • 参考文献

引入

贪心算法的思路是:希望在解决问题所要求的每一步中,都尽量选择哪个能让当前/局部(local)状态最优的做法,以希望达到全局也最优的状态。

之前的MST问题中的Kruskal算法就可以看作一种贪心算法,因为Kruskal算法就是先将边按照权重由小到大排列,然后按照这个顺序依次加入边,以希望最后得到的生成树也是最小的。

问题

活动选择(Activity Selection)

假设有一系列的活动 a i a_i ai,每个活动从某个时间点 s i s_i si开始,并且持续进行一段时间,在某个时间点 f i f_i fi结束。我们希望选择一些活动去参加,使得参加的活动的总时长最长。

贪心算法(greedy algorithms)_第1张图片

贪心算法(greedy algorithms)_第2张图片

我们可以用以上贪心算法来解决该问题,主要思路是:不断选取完成时间最早的活动来做,并且移除和被选择的活动时间有重合的其它活动。重复这个过程直到没有任何可选活动。

该贪心算法针对这个问题得到的解是最优的。

哈夫曼编码(Huffman Codes)

假设有一系列的字符,我们希望用一些二进制码来代替这些字符以进行数据压缩,使得压缩后的总比特数最小。哈夫曼编码正是这样一样压缩数据的方式。

贪心算法(greedy algorithms)_第3张图片

如果我们已知各字符在文本中的出现频率,考虑到为了让压缩后的数据更小,我们直觉是让出现频率高的字符用尽可能短的编码,而出现频率高的则可以用更长的编码。

贪心算法(greedy algorithms)_第4张图片

哈夫曼编码的解决方案是这样的:不断找到当前出现频率最小的两个结点(字符或频率),将它们结合,作为一个新生成的结点的左右子结点,并将新生成的结点继续放入比较,直到没有落单的字符。

  • 过程演示

贪心算法(greedy algorithms)_第5张图片

该贪心算法针对这个问题得到的解是最优的。

边匹配(Edge Matching)

对于一个图G,我们希望从中选取一些两两互不相邻的边,使得这样的边的数量最多。

贪心算法(greedy algorithms)_第6张图片

该贪心算法针对这个问题得到的解是不一定是最优的,但是它也确实得到了一个尽量最大化的解(Maximal)M,并且对于最优解 M ∗ M^* M,存在这样的关系:

∣ M ∗ ∣ ≤ 2 ∗ ∣ M ∣ |M^*|\le 2*|M| M2M

顶点包含(Vertex Cover)

对于一个图G,我们尝试找到一个最小的顶点的集合C,使得C中的顶点整体碰到了所有图中的边。

贪心算法(greedy algorithms)_第7张图片

但是这个算法不保证能找到最优结果,比如下面这种情况:

贪心算法(greedy algorithms)_第8张图片

所以该算法会使得集合C的大小达到 Θ ( m l g m ) \Theta(mlgm) Θ(mlgm),不过我们可以通过改进使得|C|$\le$2OPT:

贪心算法(greedy algorithms)_第9张图片

贪心算法找到全局最优解的要求

看了上面几个小实例,发现有时候贪心能找到全局最优解,有时候又不能,甚至找到的解会很差。那么决定一个贪心算法是否能找到全局最优解的条件是什么呢?

其实就是以下两点:

  • 最优子结构(optimal subproblem structure,和动态规划中的是一个概念)
  • 最优贪心选择属性(optimal greedy choice property)

01背包问题

有关01背包问题,大家具体可以看动态规划之01背包问题(最易理解的讲解)。

这里主要想讲的是,01背包问题是要求物品不可分割的,这时如果用贪心算法也无法保证全局最优。但是如果物品是可无限分割的(fractional knapsack),那么贪心又会是最优的(直觉上来说,优先将单位价值最高的物品放进背包总是没错的)。

我们可以简单证明贪心在此处的正确性:

贪心算法(greedy algorithms)_第10张图片

贪心算法(greedy algorithms)_第11张图片

参考文献

[1] Introduction to Algorithms: Third Edition, Thomas et al.

你可能感兴趣的:(Algorithm,and,Data,Structure)