定义

贪婪算法又叫贪心算法,指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。

贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。

所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。

基本步骤

❖ 建立数学模型来描述问题;

❖ 把求解的问题分成若干个子问题;

❖ 对每一子问题求解,得到子问题的局部最优解;

❖ 把子问题的局部最优解合成原来问题的一个解。

适用问题

具备贪心选择和最优子结构性质的最优化问题

贪心选择

整体的最优解可通过一系列局部最优解达到,对于一个具体问题,要确定它是否具有贪心选择的性质,我们必须证明每一步所作的贪心选择最终导致问题的最优解。做了贪心选择后,原问题可以简化成一个规模更小的类似子问题

最优子结构性质

当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质,动态规划主要运用于二维或三维问题,而贪心一般是处理一维问题

算法设计

贪心策略实现 强化学习 贪心策略基本思想_贪心算法

算法特征

❶ 随着算法的进行,将积累起其它两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已经被考虑过但被丢弃的候选对象

❷ 选择函数可以指出哪一个剩余的候选对象最有希望构成问题的解

❸ 有一个函数来检查一个候选对象的集合是否提供了问题的解答

❹ 目标函数给出解的值

❺ 另一个函数检查是否一个候选对象的集合是可行的,即是否可能往该集合上添加更多的候选对象以获得一个解

❻ 为了解决问题,需要寻找一个构成解的候选对象集合,它可以优化目标函数,贪心算法一步一步的进行。起初,算法选出的候选对象的集合为空。接下来的每一步中,根据选择函数,算法从剩余候选对象中选出最有希望构成解的对象。

2


经典案例

问题描述:有n个需要在同一天使用同一个教室的活动集合E={1,2,…,n},教室同一时刻只能由一个活动使用。每个活动都有一个开始时间s_i和结束时间f_i 。一旦被选择后,活动ai就占据半开时间区间[s_i, f_i )。如果[s_i, f_i )和[s_j, f_j )互不重叠,i和j两个活动就可以被安排在这一天。该问题就是要安排这些活动使得尽量多的活动能不冲突的举行。

算法思路:将n个活动按结束时间非减序排列,依次考虑活动i,若i与已选择的活动相容,则添加此活动到相容活动子集

设待安排的11个活动起止时间按结束时间的非减序排列

贪心策略实现 强化学习 贪心策略基本思想_最优解_02

最大相容活动子集(1,4,8,11),表示为等长n元数组(1,0,0,1,0,0,0,1,0,0,1)

算法greedySelector的计算过程如右图所示。图中每行相应于算法的一次迭代。阴影长条表示的活动是已选入集合A的活动,而空白长条是当前正在检查相容性的活动

贪心策略实现 强化学习 贪心策略基本思想_贪心策略实现 强化学习_03


3 评价

优缺点

◆ 在多数情况下容易实现且非常高效

◆ 时间和空间复杂度低,代码量小

◆ 解决了计算上的冗余问题

◆ 仅适用于最优子结构的问题

◆ 依赖于有待做出的最优选择

◆ 通常很难找到一个简单并且保证正确的贪心思路,并需要严格的正确性证明

相似算法比较

贪心策略实现 强化学习 贪心策略基本思想_贪心算法的基本思想和求解步骤_04