贪心算法(活动选择、分数背包问题)

发布于:2024-05-09 ⋅ 阅读:(43) ⋅ 点赞:(0)

一、贪心算法

        贪心算法是指:在对问题求解时,总是做出在当前看来是最好的选择,而不从整体最优考虑,做出的仅是在某种意义上的局部最优解。                                                                                            贪心算法不是对所有问题都能得到整体最优解,但能产生整体最优解或者其近似解

        基本思路:

        通过一种贪心的想法,使得得到当前的局部最优解,从而拓展至整体最优解(不一定)。所求问题的整体最优解可以通过一系列局部最优的选择,换句话说,当考虑做何种选择的时候,我们只考虑对当前问题最佳的选择而不考虑子问题的结果。这是贪心算法可行的第一个基本要素。贪心算法以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。

        贪心算法的弊端: 

              1.不能保证得到的最后解一定是最佳的,可能存在近似解(不保证一定的正确)。

              2.不能用来求最大或最小解问题。

              3.只能求满足某些约束条件的可行解的范围。

二、活动选择问题

        1.题目描述:

    假定有一个n个活动(activity)的集合S={a1, a2, ..., an},这些活动使用同一个资源(例如一个阶梯教室),而这个资源在某个时刻只能供一个活动使用。 每个活动ai都有一个开始时间si和一个结束时间fi。 如果两个活动[si, fi)和[sj, fj)不重叠,则称它们是兼容的

        目标: 找到互相兼容的最大活动子集

        互相兼容的最大活动子集样例:

   

            2.贪心思想的策略

                针对每个新活动,计算其与已经举办过的活动之间的兼容性。

                ①最早启动优先:对于所有活动,以 si 升序排列

                ②最短时长优先:以 fi - si 升序排列

                ③最少冲突优先:对于每个 i,统计与其冲突的活动数量 ci ,以 ci  升序排列

                ④最早结束优先:以 fi 升序排列

        贪心算法不保证正确性,以上四种想法,对于 ① ② ③ 均存在反例验证出其错误。

        3.贪心思想的正确性验证(最早结束优先): 

        设E={a1,a2,.....,an}为活动集合,且E中的活动是按照活动结束时间升序排列的,显然a1为最早结束。设A是问题的一个最优解,明显A是E的一个子集,设A的第一个活动为k

        ① 若 k = a1,则A的第一个活动就是最早结束的,故A是以贪心选择开始的最优解

        ② 若 k ≠ a1,设集合B=(A-{k})∪a1 ,即用活动a1可替换掉活动k

        因为a_{1}的结束时间小于k,故a_{1}k提前结束。另外由于A中的活动是相容的,故B中的活动也相容。      又因为A中的活动个数和B中的活动个数相同,故B也是最优解(需要注意的是最优解一般不唯一)。所以 B 是一个以贪心选择活动 a1 为开始后的最优解。

        或者另一种想法:

        对于最早结束的第一个活动 a1, 局部最优解考虑a1,再考虑 a2 :

         若 s2>f1 a1,a2 兼容,则问题只需要考虑 a2 ~ an,问题变成了子问题 a2 ~ an 。

         若 s2<f1  a1,a2 冲突,不考虑 a1, 令 a2 为最优解的第一个活动,则此时在 a3~an 的最优解中,加上 a1 或者 a2 的活动(不冲突时),才成为整体的最优解。此时考虑 a1 或者 a2 都是最优解,活动兼容的个数都相同,所以此贪心思想是正确的。

        4. 此外该问题还存在另一种贪心思想:

        选择最晚开始的活动依次排序考虑,其他与上述思想一致。

三、拓展问题:最少资源投入

        1.问题描述

        假定有一个n个活动的集合S={a1, a2, ..., an},这些活动可以同时使用多个资源(例如一个阶梯教室),但一个资源在某个时刻只能供一个活动使用。 每个活动 ai 都有一个开始时间 si 和一个结束时间 fi 。 如果两个活动 [ si ,  fi ) 和 [ sj , fj ) 不重叠,则称它们是兼容的

        目标: 找到最少资源数量,使得所有活动能够正常举行.

         2.贪心思想:

        ①首先将所有课程按照开始时间升序排列,并且将每门课程赋予任何可兼容的教室。

        ②通过维护一个优先队列,按照结束时间升序排列(队列首端的结束时间最早),队列中的每个元素对应着各教室的结束时间。

        ③这样当新的一个活动加入时,只需要与队首元素对应的结束时间比较,若大于结束时间则直接替换,若小于最早的结束时间,则需要加入一个元素(添加一个新的教室)

四、分数背包问题

       1.问题描述 

        给定背包容量和一些物品,每个物品有重量和价值两个属性。允许只取一个物品的一部分加入背包,求问如何才能使背包装的物品价值最大。

背包问题实质上是一个线性规划问题,可以用单纯形法、椭球法、内点法(后两者均为多项式时间算法)等求解。但在这个问题中,简单的贪心算法就能够求出最优解。

        2.贪心思想:

        既然能够取某个物品的一部分加入背包,则可以先计算出每个物品的单位重量对应的价值再从高到低依次排序,依次放入背包,直至达到背包的总容量(贪心)。

        即先取最划算的,从最划算的依次往下取。


网站公告

今日签到

点亮在社区的每一天
去签到