算法--贪心法

性质

贪心选择性质

  整体最优可通过一系列的局部最优选择,即贪心选择来达到。也就是说贪心选择是当前状态下做出的最好选择

  如何证明贪心选择是当前状态下做出的最好选择。如果可以证明存在整体的最优解包含第一步的贪心选择,那么贪心选择是当前状态下做出的最好选择。通常采用反证法证明。

使用贪心算法前一般需要“排序”数据,选择如何对数据进行排序是求解问题的关键之一。

最优子结构

一个问题的最优解包含其子结构的最优解,则称此问题具有最优子结构性质。

子问题有两种理解方式。

  • 经过贪心选择过后剩下的子问题
  • 经过k-1步贪心选择过后,载经第k步,得到的解,依然是子问题的最优解。

典例

时间安排问题

  • 问题:有n个活动,知道每个活动开始时间bi, 结束时间ei, 求一种最优活动安排方案,使得所有安排的活动个数最多。

问题求解:

  1. 排序,按结束时间ei递增排序,得到S[1…n]
  2. 局部:用flag[1…i] 记录从1到 i 的任务是否得到安排,用preend记录上一个被安排任务的结束时间
  3. 贪心选择策略:S[i].start >= preend, 则安排第i个任务,否则不安排。

证明:

  • 首先证明总存在一个以活动1开始的最优解。
      如果第一个选中的活动为k(k≠1),可以构造另一个最优解Y,Y中的活动是兼容的,Y与X的活动数相同。
       那么用活动1取代活动k得到Y’,因为e1≤ek,所以Y’中的活动是兼容的,即Y’也是最优的,这就说明总存在一个以活动1开始的最优解。
  • 当做出了对活动1的贪心选择后,原问题就变成了在活动2、…、n中找与活动1兼容的那些活动的子问题。亦即,如果X为原问题的一个最优解,则X’=X-{1}也是活动选择问题A’={i∈A | bi≥e1}的一个最优解。
      反证法:如果能找到一个A’的含有比X’更多活动的解Y’,则将活动1加入Y’后就得到A的一个包含比X更多活动的解Y,这就与X是最优解的假设相矛盾。
       因此,在每一次贪心选择后,留下的是一个与原问题具有相同形式的最优化问题,即最优子结构性质。

多机调度问题

  • 问题:有n个独立的作业和m个相同的机器,

问题求解:

  1. 排序,按作业时间递减排序, 得到S[1…n]
  2. 局部:f(i)表示对S[1…i]这i个作业进行多机调度
  3. 贪心选择策略:长作业优先

Kruskal 算法求最小生成树

证明:
(1)k=1时,首先T中没有任何边,设e1是G中权最小的边,加入e1不会产生任何回路。显然是正确的。
(2)假设算法进行了k-1步产生k-1条边,即e1,e2,…,ek-1,对应的边集合为TE1,产生的T1=(V1,TE1)是最小生成树T的子树(V1为TE1中的顶点集)。
(3)算法第k步选择了边e=(v,u),设TE2= TE1∪{e},TE2中的边把G中顶点分成两个或者两个以上的连通分量。
设S1是添加边e后包含顶点v的连通分量的顶点集,S2是添加边e后包含顶点u的连通分量的顶点集。
显然e是离开S的最短边之一(因为之前所有较短边都已经考察过,它们或者添加到T中,或者因为在同一个连通分量中而被丢弃)。
现要证明T2=(V2,TE2)也是最小生成树的子树(V2为TE2中的顶点集)。
若最终的最小生成树T包含e=(v,u),那么就不需要再进一步证明了。否则在T中S1和S2之间一定存在一条边e’=(x,y)(在后面添加的),现在再在S1和S2之间添加边e得必构成一个回路,如下图所示:
在这里插入图片描述
显然e’的权值大于或等于e的权值即cost(e’)≥cost(e),否则边e’应该在前面添加,这样由S1和S2加上e1构成的生成树的权值和大于等于T2的权值和,说明T不是最小生成树,与T是最小生成树的假设矛盾,从而证明T2是最小生成树的子树。

发布了56 篇原创文章 · 获赞 2 · 访问量 496

猜你喜欢

转载自blog.csdn.net/qq_41956860/article/details/103282617
今日推荐