⑴ 贪心算法的特性
贪婪算法可解决的问题通常大部分都有如下的特性:
⑴随着算法的进行,将积累起其它两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已经被考虑过但被丢弃的候选对象。
⑵有一个函数来检查一个候选对象的集合是否提供了问题的解答。该函数不考虑此时的解决方法是否最优。
⑶还有一个函数检查是否一个候选对象的集合是可行的,也即是否可能往该集合上添加更多的候选对象以获得一个解。和上一个函数一样,此时不考虑解决方法的最优性。
⑷选择函数可以指出哪一个剩余的候选对象最有希望构成问题的解。
⑸最后,目标函数给出解的值。
⑹为了解决问题,需要寻找一个构成解的候选对象集合,它可以优化目标函数,贪婪算法一步一步的进行。起初,算法选出的候选对象的集合为空。接下来的每一步中,根据选择函数,算法从剩余候选对象中选出最有希望构成解的对象。如果集合中加上该对象后不可行,那么该对象就被丢弃并不再考虑;否则就加到集合里。每一次都扩充集合,并检查该集合是否构成解。如果贪婪算法正确工作,那么找到的第一个解通常是最优的。

⑵ 贪心算法的本质
1. 贪心法(Greedy Algorithm)定义
求解最优化问题的算法通常需要经过一系列的步骤,在每个步骤都面临多种选择;
贪心法就是这样的算法:它在每个决策点作出在当时看来最佳的选择,即总是遵循某种规则,做出局部最优的选择,以推导出全局最优解(局部最优解->全局最优解)
2. 对贪心法的深入理解
(1)原理:一种启发式策略,在每个决策点作出在当时看来最佳的选择
(2)求解最优化问题的两个关键要素:贪心选择性质+最优子结构
①贪心选择性质:进行选择时,直接做出在当前问题中看来最优的选择,而不必考虑子问题的解;
②最优子结构:如果一个问题的最优解包含其子问题的最优解,则称此问题具有最优子结构性质
(3)解题关键:贪心策略的选择
贪心算法不是对所有问题都能得到整体最优解的,因此选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
(4)一般步骤:
①建立数学模型来描述最优化问题;
②把求解的最优化问题转化为这样的形式:对其做出一次选择后,只剩下一个子问题需要求解;
③证明做出贪心选择后:
1°原问题总是存在全局最优解,即贪心选择始终安全;
2°剩余子问题的局部最优解与贪心选择组合,即可得到原问题的全局最优解。
并完成2°
3. 贪心法与动态规划
最优解问题大部分都可以拆分成一个个的子问题,把解空间的遍历视作对子问题树的遍历,则以某种形式对树整个的遍历一遍就可以求出最优解,大部分情况下这是不可行的。贪心算法和动态规划本质上是对子问题树的一种修剪,两种算法要求问题都具有的一个性质就是子问题最优性(组成最优解的每一个子问题的解,对于这个子问题本身肯定也是最优的)。动态规划方法代表了这一类问题的一般解法,我们自底向上构造子问题的解,对每一个子树的根,求出下面每一个叶子的值,并且以其中的最优值作为自身的值,其它的值舍弃。而贪心算法是动态规划方法的一个特例,可以证明每一个子树的根的值不取决于下面叶子的值,而只取决于当前问题的状况。换句话说,不需要知道一个节点所有子树的情况,就可以求出这个节点的值。由于贪心算法的这个特性,它对解空间树的遍历不需要自底向上,而只需要自根开始,选择最优的路,一直走到底就可以了。
⑶ 贪心算法的介绍
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

⑷ 五大常用算法之一:贪心算法
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,换句话说,当考虑做何种选择的时候,我们只考虑对当前问题最佳的选择而不考虑子问题的结果。这是贪心算法可行的第一个基本要素。贪心算法以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。 对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心算法求解的关键特征。
值得注意的是,贪心算法并不是完全不可以使用,贪心策略一旦经过证明成立后,它就是一种高效的算法。比如, 求最小生成树的Prim算法和Kruskal算法都是漂亮的贪心算法 。
贪心算法还是很常见的算法之一,这是由于它简单易行,构造贪心策略不是很困难。
可惜的是,它需要证明后才能真正运用到题目的算法中。
一般来说,贪心算法的证明围绕着:整个问题的最优解一定由在贪心策略中存在的子问题的最优解得来的。
对于例题中的3种贪心策略,都是无法成立(无法被证明)的,解释如下:
贪心策略:选取价值最大者。反例:
W=30
物品:A B C
重量:28 12 12
价值:30 20 20
根据策略,首先选取物品A,接下来就无法再选取了,可是,选取B、C则更好。
(2)贪心策略:选取重量最小。它的反例与第一种策略的反例差不多。
(3)贪心策略:选取单位重量价值最大的物品。反例:
W=30
物品:A B C
重量:28 20 10
价值:28 20 10
根据策略,三种物品单位重量价值一样,程序无法依据现有策略作出判断,如果选择A,则答案错误。但是果在条件中加一句当遇见单位价值相同的时候,优先装重量小的,这样的问题就可以解决.
所以需要说明的是,贪心算法可以与随机化算法一起使用,具体的例子就不再多举了。(因为这一类算法普及性不高,而且技术含量是非常高的,需要通过一些反例确定随机的对象是什么,随机程度如何,但也是不能保证完全正确,只能是极大的几率正确)。
⑸ 贪心思想
在学习数据结构的时候,我们已经见过了贪心思想在Prim和Kruskal中的完美应用,贪心思想因为其的简洁在算法中经常会被用到,有的时候在生活中,我们也会无意中使用到l贪心算法。比如在去shopping时,经常需要进行找零钱的过程,我们总是不自觉的先把大的找出来。
那么什么是贪心思想?
贪心算法总是作出在当前看来最好的选择,也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
只有在满足最优子结构的情况下贪心算法得到的结果才是最优结果。
比如找钱的问题,我要给你一百,那么我尽可能每一次给你最多的。
或者比如磁盘的最优存储问题,所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。
Prim和kruskal算法都是每次选择最小的边纳入生成树。
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这也是贪心问题和动态规划问题的主要区别。
在n行m列的正整数矩阵中,要求从每一行中选一个数,使得选出的n个数的和最大。
可运用贪心策略,选n次,每一次选相应行中的最大值即可。
但是,在一个n*m的方格阵中,每一格子赋予一个数,规定每次移动时只能向上或向右,现试找出一条路径,使其从左下角至右上角所经过的权值之和最大。
同样考虑贪心策略,从左下角向右上角移动,每次移动选择权值较大的一个方向。
以2*3矩阵为例,采用贪心的策略得到的是1,3,4,6和为14但是实际的最优结果为1,2,100,6和为109.
所以说贪心算法并不是总是可行,证明当前问题存在贪心选择性质(全局最优解可以通过局部最优贪心选择达到)和最优子结构性质(问题的最优解包含了其子问题的最优解)。所以贪心问题如果当前的选择不会干扰之后的选择,则不会出现问题。
其他的情况就需要进行证明,证明的最好办法就是将最小子问题进行一步步的合并,直到最后还原为最后的原问题,若所得到的解是总体最优的则可以使用贪心思想,否则不可以。
比如上面的问题,我们的走一步的最优解为1,3,然后我们判断一次走两步的最优解是否任然为1,3这个路径,答案显然不是,变为 1,2,100这个路径,所以显然不能使用贪心思想。
假设1元、2元、5元、10元、20元、50元、100元的纸币分别有c0, c1, c2, c3, c4, c5, c6张。现在要用这些钱来支付K元,至少要用多少张纸币?用贪心算法的思想,很显然,每一步尽可能用面值大的纸币即可。在日常生活中我们自然而然也是这么做的。
有n个需要在同一天使用同一个教室的活动a1,a2,…,an,教室同一时刻只能由一个活动使用。每个活动ai都有一个开始时间si和结束时间fi 。一旦被选择后,活动ai就占据半开时间区间[si,fi)。如果[si,fi]和[sj,fj]互不重叠,ai和aj两个活动就可以被安排在这一天。该问题就是要安排这些活动使得尽量多的活动能不冲突的举行。
部分背包问题, 有n个物体,第i个物体重量为wi,价值为vi,在总重量不超过C的情况下,让总价值尽可能的高。每个物体都可以只取一部分。
我们可以考虑重量和价值的比值作为单价。