贪心算法经典例子


基本思想

贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。

基本思想: 贪心算法并不从整体最优上加以考虑,它所做的选择只是在某种意义上的局部最优解。
基本要素: 最优子结构性质和贪心选择性质。

和动态规划区别:
动态规划算法中,每步所做的选择往往依赖于相关子问题的解,因而只有在解出相关子问题时才能做出选择。而贪心算法,仅在当前状态下做出最好选择,即局部最优选择,然后再去解做出这个选择后产生的相应的子问题。


哈弗曼编码

前缀码: 对每一个字符规定一个0,1串作为其代码,并要求任一字符的代码都不是其他字符代码的前缀。
可以用二叉树作为前缀码的数据结构:树叶表示给定字符;从树根到树叶的路径当作该字符的前缀码,如下:
在这里插入图片描述
问题:哈夫曼提出构造最优前缀码的贪心算法,由此产生的编码方案称为哈夫曼编码。

解决思路:

  • 哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树T。
  • 算法以|C|个叶结点开始,执行|C|-1次的“合并”运算后产生最终所要求的树T。
  • 假设编码字符集中每一字符 c 的频率是 f©。以 f 为键值的优先队列 Q 用在贪心选择时有效地确定算法当前要合并的 2 棵具有最小频率的树。一旦 2 棵具有最小频率的树合并后,产生一棵新的树,其频率为合并的 2 棵树的频率之和,并将新树插入优先队列Q。经过n-1次的合并后,优先队列中只剩下一棵树,即所要求的树T。

过程如下:
在这里插入图片描述带权路径: WPL = 41 + 123 + 133 + 163 + 54 + 94


单源最短路径

问题:给定带权有向图G=(V,E),其中每条边的权都是非负数。给定一个起始顶点,成为源。计算从源到所有其他定点的最短路径长度。路径长度是各边权重之和。该问题称为单源最短路径问题。

解题思路:
Dijkstra算法(迪杰斯特拉算法)是解单源最短路径问题的贪心算法。
步骤:
(1)建立顶点集合 S ,初始只包含源点;设 u 为贪心选择的顶点,不断将 u 添加到 S 中。
(2)建立数组 dist[i],存源到 i 点的距离。若源与点 i 直接相连,则 dist[i] 等于权重,若源与 i 不直接相连,则 dist[i]=∞。
(3)选取最小的 dist[i] 对应的顶点 u 存入到 S 中。根据 S 中的顶点更新 dist[i]。
(4)重复(3)步骤,直到 S 包含所有顶点时,结束算法。
在这里插入图片描述


最小生成树

问题:在一个有权连通图中,生成树的各边权值之和称为生成树的代价。在网络的所有生成树中,权值最小的那颗生成树称为最小代价生成树,简称为最小生成树。讨论问题就是如何寻找一颗各边权的总和最小的生成树。

解决思路:

  • Prim 算法:将整个图分成两部分,一部分已选入生成树,另一部分在生成树之外。每次选的边要求一头在生成树之内,一头在生成树之外,并保证当前边是满足上述条件中最短的一条。重复上述操作,直到选出n-1条边为止。
  • Kruskal 算法:将所有的边按照权值递增的顺序排序,每次选一条权值最小的边纳入生成树中,若没有环路则选边成功,若有环路,则选下一条次小的边,直到选满n-1条边为止。
发布了96 篇原创文章 · 获赞 57 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/MOKEXFDGH/article/details/94335996
今日推荐