贪心算法
贪心算法(Greedy Algorithm),意思是每次只选择当下的最佳解,来得到最后的最佳解答案。
相较于其它算法,这个更常概念性的出现,只要算法的一部分满足这样的操作就具有贪心算法的性质,但贪心算法并非所有情况都适用。
贪心选择性质
Section titled “贪心选择性质”引用自 https://en.wikipedia.org/wiki/Greedy_algorithm#Specifics
Whichever choice seems best at a given moment can be made and then (recursively) solve the remaining sub-problems. The choice made by a greedy algorithm may depend on choices made so far, but not on future choices or all the solutions to the subproblem. It iteratively makes one greedy choice after another, reducing each given problem into a smaller one. In other words, a greedy algorithm never reconsiders its choices. This is the main difference from dynamic programming, which is exhaustive and is guaranteed to find the best (that is, the ‘optimal’) solution. After every stage, dynamic programming makes decisions based on all the decisions made in the previous stage and may reconsider the previous stage’s algorithmic path to the solution.
这段话的意思是 当下做出的局部最佳选择必定包含在最佳解之中,做出最佳选择后不再需要回溯只需要往下解决子问题就能得出最佳解的情况。
该问题的最佳解是由各个子问题的最佳解所构成的
1. 排程问题
Section titled “1. 排程问题”说明:尽可能选择最多的任务,并且时间不能重叠
start, end任务 A: [5, 9]任务 B: [1, 2]任务 C: [3, 4]任务 D: [0, 6]任务 E: [5, 7]任务 F: [8, 9]
如图所示,要选择最多的区块但不能重叠,使用贪心算法将最早完成的当作当前最佳解
-
选择当前最早完成的 B [1, 2]

-
接着从2开始,下一个起始时间>=2并且不重叠的是 C [3, 4]

-
接着从4开始,下一个起始时间>=4并且不重叠的是 E [5, 7]

-
接着从7开始,下一个起始时间>=7并且不重叠的是 F [8, 9]

-
完成,一共选择了

使用交换论证说明其符合贪心选择性质
- 所有任务
- 选择最早完成的 ( B [1, 2] )
- 假设存在一个最佳解
- 假设最佳解 不包含
- 那么 也有自己的第一个 ,
- 根据策略选择最早结束的,的完成时间必然小于等于 ,
- 新的集合
- 与 同样有 个任务
- 与 里面的其它任务 是相容的,因为
- 这表示 也可以和 里的任务相容并且数量相同, 是一个有效的解
说明其符合最优子结构
当选择了 B [1, 2] 现在可以视为是一个起始点是2的新题目
当选择了 C [3, 4] 现在可以视为是一个起始点是4的新题目
当选择了 E [5, 7] 现在可以视为是一个起始点是7的新题目
当选择了 F [8, 9] 现在可以视为是一个起始点是9的新题目
每次选择都是一个新的子问题,将这些子问题合并起来就是最终的结果
我们再来看看别的例子
2. 凑币问题_1
Section titled “2. 凑币问题_1”说明:在硬币 中使用最少的硬币凑成刚好的币值
就是平时付钱的行为,使用贪心算法每次选择最大的面额
使用交换论证说明其符合贪心选择性质
- 硬币币值
- 寻找一个大于 的临界点检验,假设目标金额
- 最佳解 ,使用硬币数量
- 若贪心选择性质成立,存在一个最佳解
- ,所以 还需要补足 ,凑出 需要
- 的硬币数量 ,,贪心选择性质不成立
说明其符合最优子结构
假设初始
当选择了最大币值 现在可以视为新题目
当选择了最大币值 现在可以视为新题目
当选择了最大币值 现在可以视为新题目
这个币值不符合 贪心选择性质 但符合 最优子结构,所以能用动态规划(Dynamic programming)解决,该章节正在撰写中
3. 凑币问题_2
Section titled “3. 凑币问题_2”说明:在硬币 中使用最少的硬币凑成刚好的币值
使用贪心算法每次选择最大的面额
使用交换论证说明其符合贪心选择性质
- 硬币币值
- 寻找一个大于 的临界点检验,假设目标金额
- 假设最佳解 不包含 ,,使用硬币数量
- 若贪心选择性质成立,存在一个最佳解
- ,所以 还需要补足 ,凑出 需要
- 的硬币数量 ,,符合结果
实际需要从最小测试到 都符合最佳解
如果 远大于 ,则最佳解必定包含 ,如同缩减成子问题的概念
而 之内可能产生复杂的交互作用。
说明其符合最优子结构
假设初始
当选择了最大币值 现在可以视为新题目
当选择了最大币值 现在可以视为新题目
货币币值是经过安排的符合标准,所以我们平时凑钱的方式总是符合预期,这篇文章提到了新增币值时确保符合贪心解法的定理。
实际解题通常不搞麻烦的证明贪心算法有效,可以判断规模 与 的关系、想个测资反例、实际尝试等方式来猜测有效性。