一、贪心算法
定义:一个算法是贪心算法,如果它是通过一些小的步骤来一个求解,并且在每一步根据局部情况选择一个决定,使得某些主要的指标得到优化。
二、区间调度问题
1. 问题:我们有一组需求{1,2,3,......,N},第i个需求与一个开始时间s(i),结束时间f(i)相对应。如果没有两个需求在时间上重叠,我们就说需求的子集是相容的。
2. 目标:寻找一个最大的相容子集O.
3. 算法:
初始令R是所有需求的集合,设A为空
While ( |R| > 0 )
选择一个最早结束的需求
把i加入到A中
在R中删除所有与i不相容的需求
End
返回集合A作为被接受的需求的集合
算法规则:该贪心算法的规则是,每一步选择一个最早结束的需求,尽快释放资源。
4. 证明算法的正确性:
假设O是最优解,由于最优解可能有多个,所以,我们只需要证明|A|=|O|,既证明集合A与集合O包含的需求个数相等。显然,A,O都是相容的,既A,O中的任意两个需要都不会重叠。
算法思想:该证明主要是想找出这样一种认识,我们的贪心算法“领先”于这个最优解O. 我们把贪心算法构造的部分解与最优解O初始的一段进行比较,并且证明贪心算法以一步接一步的方式做的更好。
假设,A = { i1,i2,......,ik }, O = { j1,j2,......,jm } ,既我们要证明k=m;同时,我们假设,A中的需求按照加入到A的顺序排序,O中的需求也按照对应区间的自然顺序排序。既有:
对任意的i,有 f(ir) <= s(ir+1)
对任意的j,有 f(jr) <= s(jr+1)
现用数学归纳法证明k=m
1)r=1 , 显然有f(i1) <= f(j1)
因为,贪心算法每一步骤都是选择最早结束的区间,故而有f(i1) <= f(j1)
2)假设第r-1步有,f(ir-1) <= f(jr-1)
3)第r步,证明f(ir-1) <= f(jr-1)
因为O是相容的,故而有:f(jr-1) <= s(jr)
又因为:f(ir-1) <= f(jr-1)
所以:f(ir-1) <= f(jr-1) <= s(jr)
既:f(ir-1) <= s(jr)
根据以上贪心算法知,在第r步区间jr 还在R中,而贪心算法的第r步是要在R中选择一个最早结束的区间ir,所以有:f(ir) <= f(jr)
总结: 对任意的r,都有f(ir) <= f(jr)
现在用反证法证明m=k,既A是最优解:
假设A不是最优解,既O中存在一个需求jk+1,该需求在jk 结束之后开始,又因为f(ik) <= f(jk),故而在需求也在ik 结束之后开始,故而jk+1与 i1,i2,......,ik相容,所以jk+1在R中;而由贪心算法知,该算法结束时R为空,故而矛盾。所以A是其中一个最优解。