Chapter 5:Greedy Algorithms
1、Greedy algorithms build up a solution piece by piece, always choosing the next piece that offers the most obvious and immediate benefit.
2、每步只看眼前效果最好的做法就是贪婪,我们希望通过局部最优达到全局最优。贪婪算法只找到一种可行解,但不一定是最优解。
3、最小生成树
- 性质一:Removing a cycle edge can not disconnect a graph
- 性质二:A tree on n nodes has n-1 edges. 树是连通且没有环的无向图。树因为其结构的简单性而具有很多应用。例如,n个结点的树有且仅有n-1条边。n个结点和n-1条边构成的图不一定是树,但如果此图是连通的,则一定是树
- 性质三:Any connected, undirected graph G = (V, E) with |E| = |V| - 1 is a tree.
- 性质四:An undirected graph is a tree if and only if there is a unique path between any pair of nodes.
4、割性质(Kruskal和prim算法的基础):假定边集X是图G = (V, E)的某个最小生成树的一部分。在图G中挑选任意一组结点S,使得X里没有边横跨S和V-S两个结点集合。假如e是所有横跨这两个集合权重最小的,则X∪{e}是某个最小生成树的一部分。
5、最小生成树的算法
- Kruskal算法
-
- 从边的角度出发,每次选择权值最小的边(贪婪)
- 如何判断是否循环?用disjoint set
- Prim算法
-
- 从顶点角度出发,步骤为
-
- 初始时,生成树的结点集U为空
- 随意选择一个结点,加入结点集,然后重复下列工作直至U=V
- 选择两个端点分别位于U和V-U中的代价最小的边(u, v)(贪婪)
- 把(u, v)加入生成树的边集,v加入到U
- Prim最小生成树算法和Dijkstra最短路径算法十分相似。Prim选择最小的边,Dijkstra选择最小的距离。
6、贪婪算法的典型应用
- 哈夫曼编码
-
- 先选择两个频率最低的字母(贪婪),将其合并为一棵子树,并将该子树的频率记为组成它的两个字母的频率之和
- 如果将开始时的每个字母看成一棵子树,则在上步后子树个数少一
- 重复上述上述步骤,直到只有一棵子树为止
- Horn formulas
- Set Cover
-
- 定义:给定一个集合B和一组B中的子集合S1,S2...Sm,如何找出改子集中的一组数量最小的子集,使得B中的所有元素均包括在选取的这组子集中?
- 贪婪策略:每次选取包含最多尚未被覆盖的子集,直到B中虽有元素被覆盖为止
- 不是最优策略,但可以证明:此策略选取的子集个数最多不会超过最优结果的ln(n)倍,其中|B| = n
- 事件序列问题
-
- 定义:给定一系列事件,已知开始时间和结束时间,对于给定一段时间,怎么安排事件,使得不重叠事件发生的数目最多?
- 贪婪策略:按结束时间排序,每次都选择最早结束且不冲突的事件