研究生课程 算法分析-贪心法

贪心法的思想

在求解一些最优化问题的时候,一般会分成多个步骤,每一步都有一个选择。贪心算法的思想在于,先不从整体考虑,每次都只做当前看来最优的思想,即局部最优解,期望通过一步步的局部最优解,最后构造出全局最优解。

贪心算法是很多问题的最优解,当然也有很多问题只是局部最优,或者近似最优解,在构造贪心算法的时候,要注意贪心选择是否能求出最后的最优解。

贪心算法的基本要素

最优子结构性质

一个问题的最优解包含其子问题的最优解,那么此问题具有最优子结构性质。前面的分治法,动态规划和此篇的贪心法,都具有最优子结构性质。

贪心选择性质

问题的整体最优解可以通过一些列局部最优的选择(贪心选择)来达到。因此贪心算法和分治法一样,都是自顶向下的思想。

贪心法的例子

0-1 背包问题

背包容量为 C ,共 n 个物品,物品 i 的(重量,价值)=(wi, vi ),求解背包装载的最大值。

贪心算法无法求出最优解。如果先按照单位价值最大排序,尽量装满背包,有时候得到的结果也近似最优解。

背包问题

和 0-1 背包不同的是,物品可以部分装载到背包中去。因此只要贪心地按照单位价值较大的物品顺序装满背包即可。

最优装载

轮船的载重量为 C ,物品 i 的重量为 Wi ,求解在体积不受限制的情况下,把最可能多的集装箱装上轮船。

可以用贪心的思想,把质量轻的物品优先装载。

哈夫曼编码

前缀码:任何一个字符的编码都不是其他字符编码的前缀(编码都是叶节点即可)
最优前缀码:使平均码长达到最小的前缀码
哈夫曼编码:自底向上构造表示最优前缀码的二叉树 T

贪心地合并两个具有最小频率的节点,并每次把合并后的节点加入到优先队列(最小堆)中去。
初始化优先队列O(n),最小堆的 removeMin 和 put 需要 O(logn)

单源最短路径

单源最短路径要解决的问题,是计算图中某个点到其他所有点的最短路径。形式化定义如下:假设带权有向图 G=(V,E),每条边的权都是非负实数,给定一个顶点,称为 源。计算从源到其他顶点的最短路长度,称单源最短路径问题。

如果边的权重都是非负的,一般用 Dijkstra 的贪心算法解决,效率较高。如果不是非负的,可以用 Bellman-Ford 算法,或者用其队列优化的改进版本,SPFS 算法。我有四篇博文讲了单源最短路径问题和这三种算法,不太详细,有空我会整理一下。我又开始挖坑了。。。

对了 Dijkstra 算法涉及优先队列和广度优先算法,还是值得一看的。

最小生成树

先定义这个问题,假设图 G 的子图 G’ 是包含所有顶点的树,那么 G’ 是图 G 的生成树,树上的总权重是该生成树的耗费,耗费最小的生成树称为 G 的最小生成树(MST,Minimum Spanning Tree)。

要计算最小生成树,可以利用贪心算法,一种是 Prim 算法,贪心地把点加入到一个集合,更新总权重;另一种是 Kruskal 算法,贪心地把圈中最小的边加入到 MST 中。

Prim 算法

思想是从一个点开始拓展,构成最小生成树(MST),每次找到剩下的点中与 MST 连接的权重最小的边 c[i][j],贪心地加入到 MST 中。

Kruskal 算法

先把边从大到小排序,贪心策略是权重小的边优先,这样把边一个个地加到 MST 中来;注意如果边在同一个连通分支中,就不能加入 MST 中,因为会构成闭环。

Kruskal 算法要用到并查集,计算时间复杂度为 O(eloge) ,比 Prim 算法的 O(n2) 要差一点,但是如果是稀疏图,边数比点数的平方少很多,那么 Kruskal 算法比 Prim 算法要好很多。

多机调度问题

多级调度问题是说,有 n 个作业,想用 m 台机器来完成,可以用“最长处理时间作业优先”的贪心策略

贪心算法的理论基础

拟阵,是个啥??【黑人问号.jpg】

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值