贪心算法就是一种非常直观的算法,对于一个问题,只关心它目前最优的解决方案,不考虑未来的发展。但往往,这种只考虑现在的算法就是最优的算法。第一步将问题分为可分的一步一步,第二步对每一步进行当前的最优计算,第三部将得到的结果最优,往往是得到的全局最优的结果。
下面还是通过课上讲解的几个例子来深入学习贪心算法。
(1)区间调度
如上图所示,第j个工作任务开始时间为sj,结束时间为fj。两个工作任务之间如果没有重叠区域,就认为它们是相容的。现在问题的目标是要找到可以同时相容的工作任务的最大子集,即最多数量。
现在对于这个问题考虑一些很自然的思路。针对这个问题,我们要选择工作。不难想出,选出所有与已经选好的工作任务相容的工作任务即可。那么如何对工作任务进行选择呢?有如下几种考虑:
1) 最早开始时间:对sj进行升序排列
2) 最早结束时间:对fj进行升序排列
3) 最短间隔:fj-sj进行升序排列
4) 最少冲突:对于每一个任务h,计数与它冲突的任务数cj。对cj进行升序排列
对于(1),(3)和(4)都能够找到反例来证明其不是最优。
其中深色任务是我们选择的,但是都并不是正确的选择。
我们再来考虑第(2)种方案。对最早结束时间进行升序排列,该算法为贪心算法,即越多越早结束的任务,同时相容的工作更多的可能性更大。
如果sj小于下一个任务的fj,那么这两个任务就是相容的。
该算法的复杂度为