程序员:Java数据结构与算法——第十七章·贪婪算法设计技术详解

本文深入探讨了贪婪算法的设计技术,通过分析贪婪策略的定义、要素、适用范围及优缺点,揭示了其在排序、优先队列、赫夫曼编码等问题中的应用。同时,文章通过实例展示了贪婪算法在某些情况下可能无法得到全局最优解的问题,强调了贪婪选择性质和最优子结构的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序员:Java数据结构与算法——第十七章·贪婪算法设计技术详解

 


17. 1引言

首先通过对一个简单理论的讨论,初步理解贪婪思想。以下棋为例,每一步的决策都需要考虑对后续棋局的影响。而在网球(或排球)比赛中,选手的行为仅取决于当前的状况,选择当下最为正确的动作,而不关心后续的影响。这说明在某些情况下选择当下最佳行为的决策,可以得到一个最优解(贪婪),但并非所有情况都如此,贪婪策略适用于上述第二类问题。


17. 2贪婪策略的定义

贪婪算法将问题分为多个阶段。在每一个阶段,选取当前状态下的最优决策,而不考虑对后续决策的影响。这意味着算法在执行过程中会选取某些局部最优解。贪婪法假.设通过局部最优解可以获得全局最优解。


17.3贪婪算法的要素

最优贪婪算法需要满足两个基本性质:

  1. 贪婪选择性质。
  2. 最优子结构。

贪婪选择性质:全局最优解可以通过寻找局部最优解获得(贪婪),局部最优解的选择可能依赖于之前的决策,而不是后续的决策。通过迭代方式算法进行一一个个贪婪选择,将原问题简化为规模更小的问题。

最优子结构:如果原问题的最优解包含子问题的最优解,则认为该问题具有最优子结构。这意味着可以对子问题求解并构建规模更大问题的解。


17.4贪婪算法的适用范围

选择局部最优解不是对于所有问题都适用,所以贪婪算法并不总是能得到最优解。在17.8节和第19章将给出这样的例子。


17.5贪婪算法的优缺点

贪婪算法的优点是直观,易于理解,并易于编码实现。当前的决策不会对已经计算出的结果有任何影响,因此不需要再对已有的局部解进行检查。缺点是,对于许多问题,无法用贪婪算法求解。即在许多情况下,无法保证局部最优解能够产生全局最优解。


17.6 贪婪算法的应用

  • 排序问题:选择排序、拓扑排序。
  • 优先队列:堆排序。
  • 赫夫曼编码压缩算法
  • Prim和Kruskal算法。
  • 加权图的最短路径问题(Dijkstra算法)。
  • 硬币找零问题
  • 分数背包问题。
  • 并查集的按大小或高度合并问题(或排名)。
  • 任务调度算法。
  • 贪婪算法可用于求解复杂问题的近似算法。

17.7贪婪思想

本节通过-一个例子来更好地理解贪婪思想,更多细节参见17.6节的相关主题。赫夫曼编码算法

定义:给定来自字母表A的n个字符的集合(字符c∈A),并已知每个字符出现的频率freq(c),为每-一个字符c∈A找到一个二进制编码,使得> freq(c) | binarycode(c) |c∈A的值最小,其中| binarycode(c) |表示字符c的二进制编码的长度。以上公式表明所有字符编码长度之和(每个字符出现频率与编码的位数乘积之和)最小。

赫夫曼编码算法的基本思想是,对于出现频率较大的字符用更少的位来编码。利用可变长度编码,赫夫曼算法可以压缩数据存储所需的空间。计算机系统采用8位来表示每一个字符, 但并非所有的位都被使用。此外,某些字符的使用更为频繁。当读取一个文件时,系统通常每次读取8位来确定-一个字符。但是这种8位编码机制是低效的,因为相比而言,有些字符使用更为频繁。例如,字符‘e'往往比字符‘q'的使用频率高10倍。

因此,如果对于字符‘e'用7位编码,而‘q'用9位编码,这将减少整个消息的长度。平均而言,对于标准文件,使用赫夫曼编码在长度上能够减少10%~30%,具体的值取决于字符的频率。这种编码思想是,对于较少使用的字符或字符组采用较长的二进制编码。此外,赫夫曼编码满足任意两个字符的编码互不为前缀。

例子:假设扫描一个文件,得出以下字符频率:

程序员:Java数据结构与算法——第十七章·贪婪算法设计技术详解

 

首先,为每一个字符创建- - 棵二叉树,并将其出现频率存储在结点中(见下图)。

程序员:Java数据结构与算法——第十七章·贪婪算法设计技术详解

 

赫夫曼算法的流程如下:在列表中寻找根结点中存有最小频率值的两棵二叉树,创建一个不存储任何字符的结点,将这两棵二叉树作为新建结点的左右子树,并将其孩子结点的频率值之和存储到新建结点中。由此可以得出下图:

程序员:Java数据结构与算法——第十七章·贪婪算法设计技术详解

 

重复.上述过程直至仅剩下一棵树。

程序员:Java数据结构与算法——第十七章·贪婪算法设计技术详解

 

程序员:Java数据结构与算法——第十七章·贪婪算法设计技术详解

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值