————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
贪心算法就是一种非常直观的算法,对于一个问题,只关心它目前最优的解决方案,不考虑未来的发展。但往往,这种只考虑现在的算法就是最优的算法。第一步将问题分为可分的一步一步,第二步对每一步进行当前的最优计算,第三部将得到的结果最优,往往是得到的全局最优的结果。
下面还是通过课上讲解的几个例子来深入学习贪心算法。
(1)区间调度
如上图所示,第j个工作任务开始时间为sj,结束时间为fj。两个工作任务之间如果没有重叠区域,就认为它们是相容的。现在问题的目标是要找到可以同时相容的工作任务的最大子集,即最多数量。
现在对于这个问题考虑一些很自然的思路。针对这个问题,我们要选择工作。不难想出,选出所有与已经选好的工作任务相容的工作任务即可。那么如何对工作任务进行选择呢?有如下几种考虑:
1) 最早开始时间:对sj进行升序排列
2) 最早结束时间:对fj进行升序排列
3) 最短间隔:fj-sj进行升序排列
4) 最少冲突:对于每一个任务h,计数与它冲突的任务数cj。对cj进行升序排列
对于(1),(3)和(4)都能够找到反例来证明其不是最优。
其中深色任务是我们选择的,但是都并不是正确的选择。
我们再来考虑第(2)种方案。对最早结束时间进行升序排列,该算法为贪心算法,即越多越早结束的任务,同时相容的工作更多的可能性更大。
如果sj小于下一个任务的fj,那么这两个任务就是相容的。
该算法的复杂度为
对于一个问题,我们首先使用贪心算法得出一个结果,再与它的最优解(可能不止一个)进行比较,看该贪心算法是否为最优。比较方法可以通过找反例,或者通过交换来证明。
证明如下:
假设该贪心算法不是最优的,那么我们来看会发生什么。
令i1,i2,…ik代表通过贪心算法选择的任务的集合,j1,j2,…jk代表最优的解决方案选择的任务的集合,假设对于两个集合前r个值一一对应相等的元素个数的最大值为r。
即下一个i(r+1)任务在j(r+1)任务之前结束,那么将i(r+1)替换j(r+1),那么原结论仍然成立(i(r+1)任务在j(r+1)任务之前结束),但是现在两个集合一一对应相等的元素个数的最大值变为r+1,与原来的假设矛盾。因此得证。
(2)区间分割
现有如下场景:
每一场讲座j开始时间为sj,结束时间为fj。现在需要找到能够安排所有讲座需要的最少的教室数量,要求在同一个教室不能有讲座冲突。由图可以看出来,这需要使用4个教室来安排10场讲座。
经过安排,可以变成下面这样:
现在就只占用了3个教室就将所有的讲座安排好,保证了没有冲突。
针对这个问题我们是在教室固定的情况下选择讲座。一个开集的集合深度是可以包含任意给定时间段最大的数量(如下图)。按照定义,需要的教室数量大于等于深度。
针对这个问题的分析,我们一开始就贪心的将所有讲座按照开始时间一一安排到相容的教室,直到不能继续在当天安排为止。同一间教室不会安排两个时间冲突的讲座。这样得到的结果被证明是最优的。
该算法的复杂度为
(3)最小延迟调度
单一资源进程一次只处理一个任务。任务j需要tj个单位的处理时间,在dj截止。如果j开始时间为s,那么结束时间为fj =sj + tj。因此,延迟为
与第一个问题类似,可以从最短处理时间优先处理,最短截止时间处理和最小的间隔(dj-tj)时间处理,我们使用贪心算法的思路是最早deadline的工作最先做,最直观的想法。并证明该思路就是最优。其余两种算法的反例如下:
如果采用最短的处理时间最小处理,那么就是先处理第1个,这样的话,这样延迟时间为1,但是如果先处理第2个,则延迟时间为0;
如果采用最短间隔时间来处理,在该例子中,则先处理第2个,那么延迟时间为9,但如果先处理第1个,则延迟时间为2.
由此我们的贪心算法思路为:
该算法的复杂度仍为
(四)最优离线缓存
存储k个条目,有cache hit和cache miss,目标为最小化cache miss的数量。可以采用farthest-in-future方法为最优。
(五)选择断点
从Princeton开车到Palo Alto,沿途会有加油站,加满是C,目标是使得能够尽可能的停下来加油。
一种贪心的思路即,开车到不能不停的时候,才停下来加油。
该算法的复杂度仍为
(六)换硬币
给定一定数额的零钱,1,5,10,25,100,找出一个方法可以使用最少数量的硬币给顾客。贪心的思路即,从最大的数额开始,再从第二大的数额开始找,一直找直到找完。
事实上,该贪心算法对于美国钱币是最优算法,但是最优一些国家的不同额度的钱币来看,并不是最优的,甚至都不能找到可行解。
如下例子:
总结这节课所讲:
Application
Method
Complexity
Interval Scheduling
Earliest-finishing
O(nlogn)
Interval Partition
Earliest-Starting
O(nlogn)
Minimize max lateness
Earliest Deadline
O(nlogn)
Optimal cache miss
Farthest-in-Future
Selecting Breakpoints
Go as far as you can
O(nlogn)
Coin changing
Change as large as possible
O(nlogn)
对于贪心算法的设计:
Step + strategy(选择候选项) +merge
版权声明:本文为博主原创文章,未经博主允许不得转载。