Greedy Algorithm 贪心算法
贪心算法总是选择当前最优的选择,有的时候并不保证正确,以下给出五个例子,前四个为准确算法,最后一个为Heuristic。
Job Schedule Problem
有一组任务,权重是 w i w_{i} wi,完成需要的时长为 l i l_{i} li,讨论两个问题。
目标是 m i n ∑ w i l i min \sum{w_{i}l_{i}} min∑wili
举例:3个任务,时长分别为1,2,3,权重为2,2,1
因为在后面的任务完成的时长需要累加等待前面任务完成的时长,不同的顺序会产生不同的目标函数结果,如下
1 − > 2 − > 3 : 1 ⋅ 2 + ( 1 + 2 ) ⋅ 2 + ( 1 + 2 + 3 ) ⋅ 1 = 14 1 -> 2 -> 3: 1\cdot2 + (1+2)\cdot2+(1+2+3)\cdot1=14 1−>2−>3:1⋅2+(1+2)⋅2+(1+2+3)⋅1=14
3 − > 2 − > 1 : 3 ⋅ 1 + ( 3 + 2 ) ⋅ 2 + ( 3 + 2 + 1 ) ⋅ 2 = 25 3 -> 2 -> 1: 3\cdot1 + (3+2)\cdot2+(3+2+1)\cdot2=25 3−>2−>1:3⋅1+(3+2)⋅2+(3+2+1)⋅2=25
观察到如果 l i l_{i} li全部相同时,先做 w w w较大的任务,相当于让他们少翻倍;如果 w i w_{i} wi全部相同时,先做 l l l较小的任务,因为每个先完成的任务后面所有任务都要重复等待相同的时间,这样可以最小化重复等待的时间。基于以上观察,考虑贪心算法,根据一个函数值从大到小决定任务顺序,这个函数应该随 w w w递增,随 l l l递减。
贪心算法:由 w i l i \frac{w_{i}}{l_{i}} liwi由大到小依次安排任务,使得 ∑ w i l i \sum{w_{i}l_{i}} ∑wili最小。
证明:算法选择的顺序为 σ = w 1 l 1 > w 2 l 2 > . . . > w n l n \sigma = \frac{w_{1}}{l_{1}} \gt \frac{w_{2}}{l_{2}} \gt ... \gt \frac{w_{n}}{l_{n}} σ=l1w1>l2w2>...>lnwn,假设存在另一顺序 σ ∗ \sigma^* σ∗,那么在 σ ∗ \sigma^* σ∗中必定存在 i < j i \lt j i<j, w i l i > w j l j \frac{w_{i}}{l_{i}} > \frac{w_{j}}{l_{j}} liwi>ljwj,但是 i i i在 j j j之后完成。不失一般性,假设 σ ∗ \sigma^* σ∗中只存在这样的一对 i , j i,j i,j,如果存在多对,则可以转化成一对多次的情况,则 σ ∗ = w 1 l 1 , w 2 l 2 , . . . , w j l j , . . . , w k l k , . . . , w i l i , . . . , w n l n \sigma^* = \frac{w_{1}}{l_{1}}, \frac{w_{2}}{l_{2}}, ..., \frac{w_{j}}{l_{j}}, ..., \frac{w_{k}}{l_{k}}, ..., \frac{w_{i}}{l_{i}}, ..., \frac{w_{n}}{l_{n}} σ∗=l1w