16. 贪心算法
求解最优化问题的算法通常需要经过一系列的步骤,在每个步骤都面临多种选择。对于许多最优化问题,使用动态规划算法来求最优解有些杀鸡用牛刀了,可以使用更简单、更高效的算法.贪心算法就是这样的算法,它在每一步都做出当时看起来最佳的选择。也就是说,它总是做出局部最优的选择,寄希望这样的选择能导致全局最优解。
活动选择问题
我们的第一个例子是一个调度竞争共享资源的多个活动的问题,目标是选出一个最大的互相兼容的活动集合。假定有一个 n 个活动的集合 S=a1,a2,...,an S = a 1 , a 2 , . . . , a n ,这些活动使用同一个资源(例如一个阶梯教室),而这个资源在某个时刻只能供一个活动使用。每个活动 ai a i 都有一个开始时间 si s i 和一个结束时间 fi f i ,其中 0≤si<fi<∞ 0 ≤ s i < f i < ∞ 。如果被选中,任务 ai a i 发生在半开时间区间 [si,fi) [ s i , f i ) 期间.如果两个活动 ai a i 和 aj a j 满足 [si,fi) [ s i , f i ) 和 [sj,fj) [ s j , f j ) 不重叠,则称它们是兼容的.也就是说,若 si≥fj s i ≥ f j 或 sj≥fi s j ≥ f i ,则 ai a i 和 aj a j 是兼容的.在活动选择问题中,我们希望选出一个最大兼容活动集。假定活动已按结束时间的单调递增顺序排序:
f1≤f2≤f3≤...≤fn−1≤fn f 1 ≤ f 2 ≤ f 3 ≤ . . . ≤ f n − 1 ≤ f n
例如下面的活动集合S:
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|
si s i | 1 | 3 | 0 | 5 | 3 | 5 | 6 | 8 | 8 | 2 | 12 |
f |