贪心算法详解分析
C语言贪心算法分析
这是《算法导论》上的例子,也是一个非常经典的问题。有 n 个需要在同一 天使用同一个教室的活动 a1,a2,…,an,教室同一时刻只能由一个活动使用。每 个活动 ai 都有一个开始时间 si 和结束时间 fi 。一旦被选择后,活动 ai 就占据半 开时间区间[si,fi)。如果[si,fi]和[sj,fj]互不重叠,ai 和 aj 两个活动就可以被安排在 这一天。该问题就是要安排这些活动使得尽量多的活动能不冲突的举行。例如下 图所示的活动集合 S,其中各项活动按照结束时间单调递增排序。
五、贪心选择性质
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的
选择,换句话说,当考虑做何种选择的时候,我们只考虑对当前问题最佳的选择 而不考虑子问题的结果。这是贪心算法可行的第一个基本要素。贪心算法以迭代 的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的 子问题。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步 所作的贪心选择最终导致问题的整体最优解。
七、例题分析
如果大家比较了解动态规划,就会发现它们之间的相似之处。最优解问题大 部分都可以拆分成一个个的子问题,把解空间的遍历视作对子问题树的遍历,则 以某种形式对树整个的遍历一遍就可以求出最优解,大部分情况下这是不可行的。 贪心算法和动态规划本质上是对子问题树的一种修剪,两种算法要求问题都具有 的一个性质就是子问题最优性(组成最优解的每一个子问题的解,对于这个子问 题本身肯定也是最优的)。动态规划方法代表了这一类问题的一般解法,我们自 底向上构造子问题的解,对每一个子树的根,求出下面每一个叶子的值,并且以 其中的最优值作为自身的值,其它的值舍弃。而贪心算法是动态规划方法的一个 特例,可以证明每一个子树的根的值不取决于下面叶子的值,而只取决于当前问 题的状况。换句话说,不需要知道一个节点所有子树的情况,就可以求出这个节 点的值。由于贪心算法的这个特性,它对解空间树的遍历不需要自底向上,而只 需要自根开始,选择最优的路,一直走到底就可以了。
贪心算法原理及应用
贪心算法原理及应用随着人工智能技术的不断发展,算法的种类也越来越多,其中贪心算法作为一种最基础的算法,也在不断优化和升级。
本文将简要介绍贪心算法原理及其应用,探讨贪心算法的优劣和适用场景。
一、贪心算法原理贪心算法是一种常见的优化算法,它的基本思想是:在每一步选择中都采取当前状态下最优的选择,从而希望最终得到全局最优的解。
贪心算法在每一步选择中都依赖于以前的选择结果,但不依赖于将来的选择结果。
这种贪心选择性质是该算法能达到最终全局最优解的保证。
然而,即使每个局部最优的选择都是正确的,但最终的全局最优解并不一定会得到,因此贪心算法不一定能得到全局最优解,但是在实际问题中,贪心算法通常可以得到非常接近最优解的结果。
二、贪心算法应用1.最小生成树最小生成树是图论中的一个经典算法问题,它可以用贪心算法来解决。
在给定一个带权无向图时,我们需要找到一棵生成树,使得生成树所有边的权值之和最小。
Prim算法和Kruskal算法都是基于这一思想建立的。
2.背包问题背包问题是一种经典的动态规划问题,也可以用贪心算法来解决。
在背包问题中,我们需要找到一种最佳的方案,使得放入背包的物品的总价值最大。
3.活动安排在一组活动中,每个活动都有一个开始时间和结束时间。
如何安排这些活动,使得可以安排的最多?可以用贪心算法进行解决。
三、贪心算法的优劣1.优点优点是:简单,易于实现;对于一些问题可以快速得到答案。
2.缺点缺点是:贪心算法不能保证得到全局最优解,只能得到最终结果接近最优解的结果。
在一些问题中会出现无解的情况。
此外,贪心算法需要根据实际问题进行调整,否则可能会得到错误的答案。
3.适用场景对于一些特殊的问题,贪心算法通常可以得到非常好的效果。
例如上文提到的最小生成树、背包问题和活动安排等等。
在这些问题中,贪心算法可以得到接近最优解的结果。
但是,在一些问题中,贪心算法的结果会偏离真实结果。
四、结语贪心算法是一种简单而实用的算法,它在很多实际问题中都有广泛的应用。
贪心算法的概念和适用条件 -回复
贪心算法的概念和适用条件-回复什么是贪心算法?贪心算法(Greedy Algorithm)是一种以局部最优解为导向的算法思想,通过每一步选择当前状态下的最佳操作来达到整体最优解的目标。
贪心算法的核心思想是每次都做出当前看来最优的选择,以期望能够达到整体的最优解。
贪心算法通常用于一些问题中,即每一步的选择只依赖于当前状态,而不考虑将来可能出现的情况。
贪心算法的适用条件:1. 贪心选择性质:贪心算法每一步都选择一个当前的最优解,此处的“最优”指的是局部最优。
这种最优选择可以确保问题能够被拆解,并且进行下一步求解。
2. 最优子结构性质:当问题的整体最优解能够通过局部最优解得到时,可以采用贪心算法求解。
这种情况下,问题的最优解可以由子问题的最优解推导出来。
3. 无后效性:贪心算法选择某一步操作时,只考虑当前状态,不会改变以前的操作,并且不关心未来的操作。
这种无后效性使得贪心算法在实际应用中操作简单、效率高。
贪心算法的基本步骤:1. 确定问题的局部最优解:贪心算法的核心是每一步都选择在当前情况下的最优解。
因此,需要确定问题如何拆解以及如何进行局部最优选择。
2. 定义问题的子问题:根据问题的最优子结构性质,将问题拆解为较小规模的子问题。
子问题应该是原问题的一个更小、更简单的实例。
3. 定义贪心选择策略:根据问题的特性,确定当前步骤下的最优选择策略。
这个选择应该是局部最优的,可以在不考虑子问题和整体未来状态的情况下得出。
4. 重复执行步骤2和3,直至求解出全局最优解。
贪心算法的优缺点:贪心算法具有简单易懂、快速高效的特点,适用于许多实际问题。
它可以避免穷举所有可能性,节省了计算时间。
此外,贪心算法常常能够找到近似最优解,尽管不一定能够保证全局最优解。
在实际问题中,近似最优解也往往可以满足实际需求。
然而,贪心算法并非适用于所有问题。
由于贪心算法只考虑当前状态的最优选择,而不考虑未来的影响,因此可能会导致局部最优解与全局最优解不一致。
贪心算法和回溯算法
贪⼼算法和回溯算法⼀.贪⼼算法 1.贪⼼算法是把⼀个复杂的问题分解为⼀个较为简单的局部最优选择,每⼀步选择都是对当前解的⼀个扩展,直到获取问题的完整。
贪⼼算法的典型运⽤是求解最优化问题,⽽且对许多问题都能得到整体最优解。
(这⾥得到的结不⼀定是最优解,但⼀定是最优解的⼗分接近的解) 2.可以使⽤贪⼼算法的要具有两个重要的性质:最优⼦结构和贪⼼选择性质 (1)最优⼦结构:在这⾥就不再说了,要看的请到上⼀章的动态规划⾥看。
(2)贪⼼选择性质:指问题的整体最优解可以通过⼀系列的局部最优的选择得到。
3.贪⼼算法和动态规划的主要区别: (1)动态规划:只要求出相关的⼦问题的解后才能做出选择 (2)贪⼼算法:仅当前的状态下做出最好的选择,即局部最优选,产⽣再去作出这样选择后产⽣的相关⼦问题的解。
4.贪⼼算法通常被使⽤来求解最优的问题,从某初始化的状态出发,根据但前的局部最优策略以满⾜约束⽅程为条件,以是⽬标函数增长最快(最慢)为准则,在候选集合进⾏⼀系列的选择,以便尽快的构成问题的可⾏解。
5.贪⼼算法的⼀般步骤: Greedy(C) //C是问题的输⼊集合,即候选集合 { S={}; //初始化解集合为空集 while(not solution(S)) //集合S没有构成问题的⼀个解 { x=select(C); //在候选集合C中做贪⼼选择 if feasible(S,x) //判断集合S中加⼊x后的解是否可⾏ { S=S+{X}; } C=C-{x}; //不管可不可⾏,都要从候选集中C删除x } return S; }⼆.回溯算法 1.回溯算法就是⼀种有组织的系统最优化搜索技术,可以看作蛮⼒法穷举搜索的改进。
回溯法常常可以避免搜索所有可能的解,所以它是⽤求解组织数量较⼤的问题。
(为什么?后⾯会解释) 2.⾸先我们先了解⼀下⼀个基本概念“解空间树”:问题的解空间⼀般使⽤解空间树的⽅式来组织,树的根节点位于第1层,表⽰搜索的初始状态,依次向下排列。
0021算法笔记——【贪心算法】贪心算法与精彩活动安排问题
0021算法笔记——【贪心算法】贪心算法与活动安排问题1、贪心算法(1)原理:在对问题求解时,总是做出在当前看来是最好的选择。
也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。
(2)特性:贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪婪法不要回溯。
能够用贪心算法求解的问题一般具有两个重要特性:贪心选择性质和最优子结构性质。
1)贪心选择性质所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。
这是贪心算法可行的第一个基本要素。
贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。
对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。
证明的大致过程为:首先考察问题的一个整体最优解,并证明可修改这个最优解,使其以贪心选择开始。
做了贪心选择后,原问题简化为规模更小的类似子问题。
然后用数学归纳法证明通过每一步做贪心选择,最终可得到问题的整体最优解。
其中,证明贪心选择后的问题简化为规模更小的类似子问题的关键在于利用该问题的最优子结构性质。
2)最优子结构性质当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。
(3)贪心算法与动态规划算法的差异:动态规划和贪心算法都是一种递推算法,均有最优子结构性质,通过局部最优解来推导全局最优解。
两者之间的区别在于:贪心算法中作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一部之前的最优解则不作保留,贪心算法每一步的最优解一定包含上一步的最优解。
易语言 贪心算法
易语言贪心算法贪心算法(Greedy Algorithm)是一种常用的算法思想,它在每一步选择中都采取当前状态下最优的选择,从而希望最终能够获得全局最优解。
本文将介绍贪心算法的基本概念、特点以及应用,并通过一些具体的例子来进一步说明其实现过程和效果。
一、贪心算法的基本概念贪心算法是一种基于贪心策略的求解问题的方法。
它通过不断地做出局部最优选择,来达到全局最优的目标。
贪心算法的基本思想是每一步都选择当前状态下最优的解决方案,而不考虑其对后续步骤的影响。
这种局部最优的选择最终希望能够达到全局最优的结果。
二、贪心算法的特点1. 简单易实现:贪心算法的实现相对简单,不需要复杂的数据结构和算法;同时,贪心算法的思想也较为直观,容易理解和应用。
2. 效率高:相比于其他算法,贪心算法通常具有较高的执行效率,时间复杂度较低。
3. 局限性:贪心算法只关注当前的最优解,而不考虑其对后续步骤的影响,因此可能会得到次优解或不正确的解。
三、贪心算法的应用贪心算法在实际问题中有着广泛的应用。
下面通过几个具体的例子来说明贪心算法的应用过程。
1. 找零问题:假设有一些零钱,如1元、5元、10元、20元、50元和100元,要用最少的零钱凑出一个给定的金额。
贪心算法可以选择面值最大的零钱来凑,然后再选择次大面值的零钱,依次类推,直到凑出给定金额为止。
2. 区间覆盖问题:假设有一些区间,需要选择尽可能少的区间来覆盖给定的目标区间。
贪心算法可以选择结束时间最早的区间,然后排除与该区间重叠的其他区间,依次类推,直到覆盖所有目标区间。
3. 集合覆盖问题:假设有一些需要覆盖的元素,以及一些集合,每个集合包含一些元素,需要选择尽可能少的集合来覆盖所有元素。
贪心算法可以选择包含最多未覆盖元素的集合,然后排除已覆盖的元素,依次类推,直到覆盖所有元素。
四、贪心算法的实现过程贪心算法的实现过程通常包括以下几个步骤:1. 确定问题的最优子结构性质。
2. 建立数学模型来描述问题。
最优装载问题(贪心)
最优装载问题(贪⼼)⼀、实验内容运⽤贪⼼算法解决活动安排问题(或最优装载问题)使⽤贪⼼算法解决最优装载问题。
⼆、所⽤算法基本思想及复杂度分析1.算法基本思想贪⼼算法是指在对问题求解时,总是做出在当前看来是最好的选择。
也就是说,不从整体最优上加以考虑,它所做出的仅是在某种意义上的局部最优解。
⽤局部解构造全局解,即从问题的某⼀个初始解逐步逼近给定的⽬标,以尽可能快的求得更好的解。
当某个算法中的某⼀步不能再继续前进时,算法停⽌。
2.问题分析及算法设计问题分析:(1)给定n个古董,要把它们装到装载量为c的装载船上。
(2)⾸先需要对这n个古董进⾏质量从⼩到⼤的排序。
(3)然后每次都选择最轻的,接着再从剩下的n-1件物品中选择最轻的。
(4)重复第(3)步骤,直到当前载重量⼤于装载船的最⼤装载量,停⽌装载。
(5)此时得到最优的贪⼼⽅案,记录下装载的最⼤古董数。
算法设计:(1)算法策略:把n件物品从⼩到⼤排序,然后根据贪⼼策略尽可能多的选出前i个物品,直到不能装为⽌。
(2)特例:算法复杂度分析由最优装载问题的贪⼼选择性质和最优⼦结构性质,可知将这些古董按照其重量从⼩到⼤排序,所以算法所需的计算时间为O(nlogn)。
三、源程序核⼼代码及注释(截图)四、运⾏结果五、调试和运⾏程序过程中产⽣的问题及解决⽅法,实验总结(5⾏以上)这⾥的调试,没有什么⼤问题,单纯的依次⽐较,判断,从⽽得到结果。
这次实验让我对贪⼼算法有了更深刻的认识,其主要是从问题的初始解出发,按照当前最佳的选择,把问题归纳为更⼩的相似的⼦问题,并使⼦问题最优,再由⼦问题来推导出全局最优解。
贪⼼算法虽然求的是局部最优解,但往往许多问题的整体最优解都是通过⼀系列的局部最优解的选择来达到的,所以贪⼼算法不⼀定可以得到能推导出问题的最优解,但其解法是最优解的近似解。
懂得算法的原理,还需要多去练习才能更好的掌握其⽤法。
源码:#include<iostream>#include<algorithm>#define MAXN 1000005using namespace std;int w[MAXN];//每件古董的重量int main(){int c,n;//c:载重量,n古董数int sum = 0;//装⼊古董的数量int tmp = 0;//装⼊古董的重量cin >> c >> n;for(int i= 1; i <= n; ++i)cin >> w[i];sort(w+1,w+1+n);for(int i = 1; i <= n; ++i){tmp += w[i];if(tmp <= c)++sum;elsebreak;}cout << sum << endl;return 0;}。
贪心算法的图文讲解
总结
• 在对问题求解时,会选择当前看起来最有希望成功的边(任务) 。一旦做出决定,它就不会再重新考虑,也不会关心后面会引发 什么情况。也就是说,不从整体最优上加以考虑,它所做出的是 在某种意义上的局部最优解。 • 贪心算法是一种能够得到某种度量意义下的最优解的分级处理方 法,通过一系列的选择来得到一个问题的解,而它所做的每一次 选择都是当前状态下某种意义的最好选择,即贪心选择。即希望 通过问题的局部最优解来求出整个问题的最优解。这种策略是一 种很简洁的方法,对许多问题它能产生整体最优解,但不能保证 总是有效,因为它不是对所有问题都能得到整体最优解,只能说 其解必然是最优解的很好近似值
对于这个问题我们有以下几种情况:设加油次数为k,每个加油 站间距离为a[i];i=0,1,2,3……n (1)始点到终点的距离小于N,则加油次数k=0; (2)始点到终点的距离大于N时: A 加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n ; B 加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点; C 加油站间的距离相等,即a[i]=a[j]=L<N,则加油次数 k=n/N(n%N==0)或k=[n/N]+1(n%N!=0); D 加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过贪心 算法求解。
•
• • 贪心的基本思想
• 用局部解构造全局解,即从问题的某一个初始解逐步逼 近给定的目标,以尽可能快地求得更好的解。当某个算 法中的某一步不能再继续前进时,算法停止。贪心算法 思想的本质就是分处理 出一个最好的方案。 • 利用贪心策略解题,需要解决两个问题: • (1)该题是否适合于用贪心策略求解; • (2)如何选择贪心标准,以得到问题的最优/较优解。
贪心算法解析
贪心算法解析在计算机科学领域中,贪心算法是一种简单却高效的算法,主要用于解决优化问题。
贪心算法的基本思想是:每一步都选择当前最优的解决方案,最终得到全局最优解。
贪心算法的核心在于贪心策略。
贪心策略是指每一步都选取当前最优解,即对当前局部最优解不做考虑就直接进行决策。
贪心算法的优点在于其时间复杂度比较低,常常能够在很短的时间内找到一个不错的解决方案。
但是,使用贪心算法求解问题时需要注意,贪心算法要求问题具有最优子结构性质(即所有子问题的最优解能够推导出全局最优解),而且贪心算法并不能保证求得最优解。
下面通过几个实例来讲解贪心算法的应用。
例一:找零钱问题假设我们有 $n$ 种面额不同的硬币,它们的面值分别为 $v_1, v_2, ..., v_n$。
我们要找回 $p$ 元钱,问最少需要多少枚硬币。
这个问题可以用贪心算法来解决。
贪心策略是每次取尽量大的面额,直到找回的零钱等于 $p$ 元为止。
具体步骤如下:1. 将硬币按照面额从大到小排序;2. 依次取硬币,如果当前硬币的面额小于要找的零钱,就继续取;否则,取下一个硬币;3. 当找回的钱数等于 $p$ 时停止。
为了证明这个贪心算法确实是正确的,我们可以假设另外有一种更优的算法。
我们可以证明,如果这个算法与贪心算法在某一步不同时,那么这个算法肯定不是最优解。
因此,我们只需要证明贪心算法的每一步都能得到最优解,即可证明贪心算法是正确的。
例二:活动安排问题假设有一组活动,每个活动都有开始时间和结束时间。
假设活动 $i$ 的开始时间为 $s_i$,结束时间为 $f_i$。
问最多可以安排多少个活动。
这个问题可以用贪心算法来解决。
贪心策略是每次选择结束时间最早的活动。
具体步骤如下:1. 将活动按照结束时间从早到晚排序;2. 选择剩余结束时间最早的活动,将其加入集合中,将其结束时间赋值给变量 $last$;3. 对于接下来的活动,若其开始时间 $s_i \geq last$,则将其加入集合中,将其结束时间赋值给 $last$;否则,忽略这个活动。
计算机算法贪心算法基础知识全面解析
计算机算法贪心算法基础知识全面解析计算机算法是计算机科学中的重要分支,它研究了如何有效地解决问题和执行任务。
在算法的研究中,贪心算法是一种常用且重要的策略。
本文将全面解析贪心算法的基础知识,包括其定义、特点、应用场景和实现方法。
一、贪心算法的定义和特点贪心算法是一种通过每一步的最优选择,最终达到整体的最优解的策略。
它的基本思想是总是做出在当前状态下看起来最好的选择,而不考虑其对未来的影响。
贪心算法具有以下特点:1. 简单:贪心算法通常思路简单,易于理解和实现。
2. 高效:贪心算法的时间复杂度通常较低,能够在较短的时间内得到近似最优解。
3. 局部最优:贪心算法每一步的选择都是局部最优的,但不一定能够得到全局最优解。
二、贪心算法的应用场景贪心算法在解决一些最优化问题、组合优化问题和调度问题等方面有广泛的应用。
下面列举几个常见的应用场景。
1. 钱币找零:给定不同面额的硬币和一个要找零的金额,贪心算法可以求解找零所需的最小硬币数。
2. 区间覆盖:给定一组区间,选择尽可能少的区间,使得它们的并集覆盖给定的区间。
3. 任务调度:给定一组任务和它们所需的执行时间,贪心算法可以求解在最短时间内完成所有任务的调度顺序。
4. 哈夫曼编码:根据字符出现的频率构建最优的前缀编码树,用于数据压缩和传输。
三、贪心算法的实现方法贪心算法的实现通常分为以下两种方法:1. 按优先级选择:根据问题的具体要求,将可选的方案按照优先级进行排序,每次选择优先级最高的方案。
2. 按增量选择:从问题的初始状态开始,通过每一步的选择逐步构建解决方案,直到达到最终状态。
不同的问题会适用不同的实现方法,需要根据具体情况选择最合适的策略。
总结:贪心算法是一种常用且重要的算法策略,通过每一步的最优选择达到整体最优解。
它的简单性和高效性使得它在实际问题中有广泛的应用。
我们通过定义和特点、应用场景以及实现方法等方面,对贪心算法的基础知识进行了全面解析。
对于进一步学习和探索贪心算法,可以深入研究不同应用领域下的具体案例和算法实现。
贪心算法及其应用
贪心算法及其应用近年来,随着科技的发展和数据的爆炸式增长,优化问题成为了研究的热点。
在高效解决各种优化问题中,贪心算法发挥了重要作用。
本文将介绍贪心算法的定义、特点、优缺点及其常见应用。
一、什么是贪心算法贪心算法是一种常见的算法方法,通过贪心策略来求解问题的最优解。
其思想是在每一个阶段上,选择当前最优解的策略,最终得到的就是问题的最优解。
二、贪心算法的特点贪心算法具有以下特点:1、局部最优解一定是全局最优解的一个组成部分;2、求解过程中不需要回溯;3、贪心算法具有高效性,时间复杂度低。
三、贪心算法的优缺点1、优点贪心算法具有简单、高效等优点。
对于那些没有明确要求最优解的问题,贪心算法是一个不错的选择。
2、缺点贪心算法的局限性在于,有些问题不能用贪心策略求得最优解。
因为每一步选择的最优解并不一定能导致全局最优解。
此外,贪心算法需要注意到问题的结构性质,否则可能做出错误决策。
四、贪心算法的应用1、背包问题背包问题是一个最经典的贪心算法应用场景。
在这个问题中,我们需要将一组物品放到一个容器中。
每个物品有一个权值和一个体积。
容器有一个最大承载体积,求容器可以承载的最大权值。
使用贪心算法在背包问题中是具有局限性的。
但是,在有些情况下,贪心策略是可行的。
例如在只考虑单个维度时,贪心算法以效率极高的速度求得其最优解。
2、最小生成树最小生成树问题是一个常见的求解问题。
其问题的目标是在一张图中找到一棵生成树,该树的所有边权之和最小。
在这个问题中,我们采用贪心策略选择当前最优边并添加到生成树中,以此来求得最优解。
3、哈夫曼编码哈夫曼编码是一种广泛应用的数据压缩算法。
其通过根据字符出现频率选择具有最小权值的二叉树节点,最终构建出哈夫曼树,以此来表示字符的编码信息。
使用哈夫曼编码可以实现对数据的高效压缩和解压缩。
4、调度问题在调度问题中,我们需要找到一种方案,让若干任务在满足约束条件的前提下,以最短的时间完成。
例如,在机器调度问题中,我们需要为不同机器安排任务以最小化整体完成时间。
贪心算法的应用
贪心算法的应用贪心算法是一种经典的算法思想,它在解决一些优化问题时具有很高的效率和实用性。
本文将介绍贪心算法的原理和应用,并以实际场景为例,详细讲解贪心算法的实施过程。
一、贪心算法简介贪心算法是一种基于贪心策略的算法思想,即每一步都选择当前最优解,以期望最终能够达到全局最优解。
它的核心思想是通过不断地做出局部最优选择,从而达到全局最优。
贪心算法通常适用于满足“最有子结构性质”的问题,即通过局部最优解来推导出全局最优解。
二、贪心算法的应用场景贪心算法的应用非常广泛,以下将介绍几个常见的应用场景。
1. 零钱找零问题假设我们需要找零n元,而手上只有面额为1元、2元、5元的硬币若干。
为了找零的硬币数量最少,我们可以采用贪心算法的思想:每一步选择面额最大的硬币,再找零,直到找够n元为止。
2. 区间调度问题给定一个由n个区间组成的集合,每个区间都有一个起始时间和结束时间,我们的目标是在不重叠的前提下,尽量多地选择区间。
解决这个问题的贪心策略是选择结束时间最早的区间,再继续选择剩余区间中结束时间最早的区间,依次类推。
3. 最优装载问题假设有一批货物和一个固定容积的仓库,每个货物有自己的体积和价值。
我们的目标是在仓库容积有限的情况下,选择部分货物使得总价值最大化。
贪心算法可以通过按单位价值排序,每次选择价值最高的货物进行装载,直到仓库容量不足为止。
三、贪心算法的实施过程以区间调度问题为例,介绍贪心算法的实施过程。
1. 首先,将所有区间按照结束时间进行排序。
2. 初始化一个空的结果集res,将第一个区间加入res中。
3. 从第二个区间开始遍历,若当前区间的起始时间大于等于res中最后一个区间的结束时间,则将该区间加入res中。
4. 遍历完所有区间后,res中存放的就是最优解。
通过上述过程,我们可以得到最大化选择的不重叠区间集合,从而解决了区间调度问题。
四、贪心算法的优缺点贪心算法的优点是简单、高效,可以快速地得到一个近似最优解。
贪心算法的理解-概述说明以及解释
贪心算法的理解-概述说明以及解释1.引言1.1 概述概述部分的内容可以描述贪心算法的基本概念和作用。
贪心算法是一种常用的求解优化问题的算法思想,其核心思想是在每一步都选择当前最优解,从而希望最终达到全局最优解。
贪心算法通常适用于那些具有最优子结构特性和贪心选择性质的问题。
具体来说,贪心算法通常分为以下几个步骤:首先,根据问题的特性确定问题的目标函数或者判断问题的可行解的标准;其次,把原问题分解为若干个子问题,每次选择最优解作为当前问题的解;接着,对所选取的解进行判断,如果满足问题的约束条件,则放入解集中,否则舍弃;最后,递归或者迭代地处理下一个子问题,直到找出全局最优解。
贪心算法的应用非常广泛,它可以用来解决许多实际问题,比如最小生成树、最短路径、背包问题等。
贪心算法的优点在于简单、高效,其时间复杂度通常较低。
然而,贪心算法也有其局限性,它只关注当前的最优解而不考虑全局的最优解,因此在某些问题上可能会得到次优解甚至是错误的解。
综上所述,贪心算法是一种重要的优化算法思想,通过不断选择当前最优解来求解问题。
它的应用广泛,具有高效简单的特点,但也存在局限性。
在今后的发展中,我们可以对贪心算法进行改进,使其在更多的问题中发挥更强大的作用。
1.2 文章结构文章结构部分:本文分为引言、正文和结论三个部分。
引言部分主要概述了本文的主题——贪心算法,并介绍了文章的结构和目的。
正文部分将重点讲解贪心算法的定义、原理、应用场景以及优缺点。
首先,在2.1节中,我们将介绍什么是贪心算法。
贪心算法是一种在每一步选择中都选择当前情况下最好或最优的选择,以期望能够导致全局最优解的算法。
其次,在2.2节中,我们将详细解析贪心算法的原理。
贪心算法的核心思想是通过不断地做出局部最优选择,从而最终得到全局最优解。
我们将使用一些具体的示例来说明贪心算法的运作方式。
然后,在2.3节中,我们将探讨贪心算法的应用场景。
贪心算法在很多实际问题中都有广泛的应用,如任务调度、背包问题、最短路径等。
算法设计中的贪心思想
算法设计中的贪心思想贪心思想是一种常见的算法设计思想,它通常用于优化问题。
贪心思想的核心思想是在每个子问题中选择最优解,从而得到全局最优解。
在本文中,将讨论贪心思想在算法设计中的应用及优缺点。
一、贪心思想的基本原理贪心算法在解决问题时,会在每个子问题中选择当前的最优解,而不会考虑将来会产生的影响。
这种局部最优解的选择,最终会得到整体最优解。
简单的说,贪心算法就是以当前状态为最优状态。
二、贪心算法的应用1.活动选择问题活动选择问题是在一定时间内选择活动的过程,活动有开始和结束的时间,需要选择不冲突的最多的活动。
贪心算法在此问题中的应用就是优先选择结束时间最早的活动,这样才能腾出更多的时间去选择其他活动。
2.背包问题背包问题是在一定容量的背包中,选择物品使得背包中物品价值最大。
贪心算法在此问题中的应用就是优先选择单价最高的物品,这样可以最大化背包中物品的价值。
3.霍夫曼编码问题霍夫曼编码是一种将字符串进行无损压缩的方法。
贪心算法在此问题中的应用就是优先选择频率最低的字符进行编码,这样可以最大程度地减小编码的长度。
三、贪心算法的优缺点1.优点贪心算法通常是高效的,因为它只考虑了当前状态的最优解,而不需要考虑所有子问题的最优解。
在某些情况下,贪心算法可以得到最优解,例如活动选择问题、霍夫曼编码问题等。
2.缺点贪心算法的局限性在于,它不能保证在所有情况下都能得到最优解。
因为贪心算法只考虑了当前状态的最优解,而没有考虑将来的影响。
当某个子问题的最优解与整体最优解不一致时,贪心算法可能会失效。
例如背包问题中,如果贪心算法优先选择单价最高的物品,而没有考虑物品的重量,就有可能导致最终选取的物品组合无法放入背包中。
四、结论综上所述,贪心思想是一种常见的算法设计思想,它在优化问题中的应用非常广泛。
虽然贪心算法不能保证在所有情况下都能得到最优解,但在某些特定问题中,贪心算法仍然是最优解的选择。
因此,在使用贪心算法时,需要深入了解问题本身的性质,权衡利弊,以保证算法的有效性。
贪心算法理解贪心算法的基本原理和应用场景
贪心算法理解贪心算法的基本原理和应用场景贪心算法:理解贪心算法的基本原理和应用场景简介:贪心算法(Greedy Algorithm)是一种常用的算法设计和解决问题的方法。
它以一种贪婪的方式做出每一步的选择,希望最终能够达到整体上的最优解。
本文将介绍贪心算法的基本原理和常见应用场景。
一、贪心算法的基本原理贪心算法的基本原理是每次都做出当前最优的选择,希望最终能够达到整体上的最优解。
贪心算法的优点在于简单、高效,但由于它只关注当前最优解,因此可能无法得到全局最优解。
贪心算法的基本步骤如下:1. 将问题划分为若干子问题,每个子问题都有多个选择;2. 分析子问题的选择,以及每个选择的最优解;3. 根据每个子问题的最优解,做出当前最优的选择;4. 更新已做出选择的子问题集合;5. 重复步骤3和4,直到解决全部子问题。
二、贪心算法的应用场景1. 零钱兑换问题零钱兑换问题是指给定一个金额和一组零钱的面值,如何用最少数量的零钱找零。
贪心算法可以从面值最大的零钱开始,每次找零选择当前面值最大的零钱,直到达到目标金额。
2. 区间调度问题区间调度问题是指给定一组区间,如何选择最多数量的不相交区间。
贪心算法可以根据区间的结束时间进行排序,每次选择结束时间最早的区间,并排除与之重叠的其他区间。
3. 背包问题背包问题是指给定一组物品和一个固定容量的背包,如何选择物品放入背包,使得背包中物品的总价值最大。
贪心算法可以通过计算每个物品的单位价值(即物品的价值与重量的比值)来选择单位价值最高的物品放入背包。
4. 最短路径问题最短路径问题是指在一个有向图或无向图中,找到两个节点之间的最短路径。
贪心算法可以使用Dijkstra算法,每次选择离起始节点最近的未访问节点进行扩展,直到找到目标节点。
5. 活动选择问题活动选择问题是指在一组活动中,选出最大的互相兼容的活动子集合。
贪心算法可以根据活动的结束时间进行排序,每次选择结束时间最早的活动,并排除与之重叠的其他活动。
贪心算法
6.贪心方法模型
a.工程计划模型 b.部分背包与每步最优 c.构造贪心算法
a.工程计划模型
我们常常碰到这样的问题:完成一个工程需
要若干个步骤,每个步骤都有若干种方法, 图示—— 步骤a 步骤b 步骤c ... 步骤n 方法b1 方法c1 方法a1 方法b2 方法c2 方法n1 方法a2 方法b3 方法c3 方法c4
种树问题:一条街道分为n个区域(按1-n编号), 每个都可种一棵树。有m户居民,每户会要求在区 域i-j区间内种至少一棵树。现求一个能满足所有要 求且种树最少的方案。 算法构造: 1.对于要求,以区间右端(升序)为首要关键字, 左端(升序)为次要关键字排序。 2.按排好的序依次考察这些要求,若未满足,则在 其最右端的区域种树,这时可能会满足多个要求。 证明思路:解法并不唯一,关键是证明没有比该解 法更好的解法。按步骤1排序之后,会发现对于每 个要求,在最右边的区域内种树所得的结果总不会 差于在其他区域种树。至于为什么这样排序,留给 你——读者们思考吧。
每个方法有一个权值(如效率、质量),其大小往 往和其他步骤中选取的方法有关。有些时候权值无 意义,表示方法不可选择。要求给出一个方法组合, 是权值和最大。 在这里,暂且把它称作“工程计划”。很多实际问 题都可以归纳为这个模型。 对于不同形式的工程计划,我们有不同的解法。 若权值与整个过程或前后步骤的方法选择都有关, 我们使用搜索算法——时间复杂度高得吓人。 若每个权值只与上(或下)一步或少数几步的方法 选择都有关,我们使用动态规划——有比较高的效 率,在下一章会讲到。 若每个权值与其他步骤的方法选择都没有关系,我 们使用贪心方法。
算法分析:设a[i]为第I堆纸牌的张数(0<=I<=n), v为均分后每堆纸牌的张数,s为最小移动次数。 我们用贪心算法,按照从左到右的顺序移动纸牌。 如第I堆的纸牌数不等于平均值,则移动一次(即s 加1),分两种情况移动: 1.若a[i]>v,则将a[i]-v张从第I堆移动到第I+1堆; 2.若a[i]<v,则将v-a[i]张从第I+1堆移动到第I堆。 为了设计的方便,我们把这两种情况统一看作是将 a[i]-v从第I堆移动到第I+1堆,移动后有a[i]=v; a[I+1]=a[I+1]+a[i]-v. 在从第I+1堆取出纸牌补充第I堆的过程中可能回出 现第I+1堆的纸牌小于零的情况。
贪心算法详解
第16章贪心算法理解贪心算法的概念zz掌握贪心算法的基本要素z理解贪心算法与动态规划算法的差异z通过范例学习贪心算法设计策略16116.1 活动安排问题z当一个问题具有最优子结构性质时,可用动态规划法求解,但有时用贪心算法求解会更加的简单有效。
z顾名思义,贪心算法总是作出在当前看来最好的选择。
也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
当然,希望贪心算法得到的最终结果也是整体最优的。
虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。
单源最短路经问题,最小生成树问题等。
在些情解。
如单源最短路经问题,最小生成树问题等。
在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。
161z设有n个活动的集合E={1,2,…,n},其中每个活动都要求使16.1活动安排问题用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。
每个活动i都有一个要求使用该资源和个结束时间f 且s 如果选择了活动i 的起始时间s i 和一个结束时间f i ,且s i <f i 。
如果选择了活动i,则它在半开时间区间[s i , f i )内占用资源。
若区间[s i , f i )与区间[s , f 活动i与活动j是相容的。
也就是说,间[j ,j )不相交,则称活动与活动j是相容的也就是说,当s i ≥f j 或s j ≥f i 时,活动i与活动j相容。
z问题:选出最大的相容活动子集合。
16.1 活动安排问题161(用动态规划方法)z步骤1:分析最优解的结构特征—构造子问题空间:S ij={ a k∈S: f i≤s k<f k≤s j}S ij包含了所有与a i和a j相兼容的活动,并且与不迟于a i结束和不早于a j 开始的活动兼容。
此外,虚构活动a0和a n+1,其中f00, S n+1。
原=0,S=∞。
原问题即为寻找S0,n+1中最大兼容活动子集。
贪心算法(Greedy)
例如, 例如,设7个独立作业{1,2,3,4,5,6,7}由3台 机器M1,M2和M3加工处理。各作业所需的处理时 间分别为{2,14,4,16,6,5,3}。按算法greedy greedy产生 greedy 的作业调度如下图所示,所需的加工时间为17。
约定,每个作业均可在任何一台机器上加工处理, 约定,每个作业均可在任何一台机器上加工处理,但未 完工前不允许中断处理。作业不能拆分成更小的子作业。 完工前不允许中断处理。作业不能拆分成更小的子作业。
采用最长处理时间作业优先 最长处理时间作业优先的贪心选择策略可以设计 最长处理时间作业优先 出解多机调度问题的较好的近似算法。 按此策略,当 n ≤ m时,只要将机器i的[0, ti]时间区间 分配给作业i即可,算法只需要O(1)时间。 i O(1) 当 n > m 时,首先将n个作业依其所需的处理时间从大 到小排序。然后依此顺序将作业分配给空闲的处理机。算 法所需的计算时间为O(nlogn)。
void Knapsack(int n,float M,float Knapsack(int v[],float w[],float x[]) { Sort(n,v,w); int i; for (i=1;i<=n;i++) x[i]=0; float c=M; for (i=1;i<=n;i++) { if (w[i]>c) break; x[i]=1; c-=w[i]; } if (i<=n) x[i]=c/w[i]; }
用贪心算法解背包问题的基本步骤:
首先计算每种物品单位重量的价值Vi/Wi,然后,依贪心 首先计算每种物品单位重量的价值Vi/Wi,然后,依贪心 选择策略,将尽可能多的单位重量价值最高 选择策略,将尽可能多的单位重量价值最高的物品装入背包。 单位重量价值最高的物品装入背包。 若将这种物品全部装入背包后,背包内的物品总重量未超过 C,则选择单位重量价值次高的物品并尽可能多地装入背包。 依此策略一直地进行下去,直到背包装满为止。 具体算法可描述如下页:
贪心算法的C语言实现与运用详解
贪⼼算法的C语⾔实现与运⽤详解贪⼼算法所谓贪⼼算法是指,在对问题求解时,总是做出在当前看来是最好的选择。
也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。
贪⼼算法不是对所有问题都能得到整体最优解,但对范围相当⼴泛的许多问题他能产⽣整体最优解或者是整体最优解的近似解。
贪⼼算法的基本思路如下:1.建⽴数学模型来描述问题。
2.把求解的问题分成若⼲个⼦问题。
3.对每⼀⼦问题求解,得到⼦问题的局部最优解。
4.把⼦问题的解局部最优解合成原来解问题的⼀个解。
实现该算法的过程:从问题的某⼀初始解出发;while 能朝给定总⽬标前进⼀步do 求出可⾏解的⼀个解元素;由所有解元素组合成问题的⼀个可⾏解;#include "stdio.h"void main(){int act[11][3]={{1,1,4},{2,3,5},{3,0,6},{4,5,7},{6,5,9},{7,6,10},{8,8,11},{9,8,12},{10,2,13},{11,12,14}};greedy(act,11);getch();}int greedy(int *act,int n){int i,j,no;j=0;printf("Selected activities:/n");no=0;printf("Act.%2d: Start time %3d, finish time %3d/n", act[no],act[no+1],act[no+2]);for(i=1;i<n;i++){no=i*3;if(act[no+1]>=act[j*3+2]){j=i;printf("Act.%2d: Start time %3d, finish time %3d/n", act[no],act[no+1],act[no+2]);}}}例题题⽬描述:⼜到毕业季,很多⼤公司来学校招聘,招聘会分散在不同时间段,⼩明想知道⾃⼰最多能完整的参加多少个招聘会(参加⼀个招聘会的时候不能中断或离开)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
贪心算法详解贪心算法思想:顾名思义,贪心算法总是作出在当前看来最好的选择。
也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
当然,希望贪心算法得到的最终结果也是整体最优的。
虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。
如单源最短路经问题,最小生成树问题等。
在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。
贪心算法的基本要素:1.贪心选择性质。
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。
这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。
动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。
对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。
2. 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。
问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。
贪心算法的基本思路:从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。
当达到算法中的某一步不能再继续前进时,算法停止。
该算法存在问题:1. 不能保证求得的最后解是最佳的;2. 不能用来求最大或最小解问题;3. 只能求满足某些约束条件的可行解的范围。
实现该算法的过程:从问题的某一初始解出发;while 能朝给定总目标前进一步do求出可行解的一个解元素;由所有解元素组合成问题的一个可行解;用背包问题来介绍贪心算法:背包问题:有一个背包,背包容量是M=150。
有7个物品,物品可以分割成任意大小。
要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。
物品A B C D E F G重量35 30 60 50 40 10 25价值10 40 30 50 35 40 30分析如下目标函数:∑pi最大约束条件是装入的物品总重量不超过背包容量:∑wi<=M( M=150)。
(1)根据贪心的策略,每次挑选价值最大的物品装入背包,得到的结果是否最优?(2)每次挑选所占重量最小的物品装入是否能得到最优解?(3)每次选取单位重量价值最大的物品,成为解本题的策略。
值得注意的是,贪心算法并不是完全不可以使用,贪心策略一旦经过证明成立后,它就是一种高效的算法。
贪心算法还是很常见的算法之一,这是由于它简单易行,构造贪心策略不是很困难。
可惜的是,它需要证明后才能真正运用到题目的算法中。
一般来说,贪心算法的证明围绕着:整个问题的最优解一定由在贪心策略中存在的子问题的最优解得来的。
对于背包问题中的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,则答案错误。
但是果在条件中加一句当遇见单位价值相同的时候,优先装重量小的,这样的问题就可以解决.所以需要说明的是,贪心算法可以与随机化算法一起使用,具体的例子就不再多举了。
(因为这一类算法普及性不高,而且技术含量是非常高的,需要通过一些反例确定随机的对象是什么,随机程度如何,但也是不能保证完全正确,只能是极大的几率正确)。
下面我们看一些简单例题。
例24:在N行M列的正整数矩阵中,要求从每行中选出1个数,使得选出的总共N个数的和最大。
分析:要使总和最大,则每个数要尽可能大,自然应该选每行中最大的那个数。
因此,我们设计出如下算法:读入N, M,矩阵数据;Total := 0;For I := 1 to N do begin {对N行进行选择}选择第I行最大的数,记为K;Total := Total + K;End;输出最大总和Total;从上例中我们可以看出,和递推法相仿,贪心法也是从问题的某一个初始解出发,向给定的目标递推。
但不同的是,推进的每一步不是依据某一固定的递推式,而是做一个局部的最优选择,即贪心选择(在例中,这种贪心选择表现为选择一行中的最大整数),这样,不断的将问题归纳为若干相似的子问题,最终产生出一个全局最优解。
特别注意的是是,局部贪心的选择是否可以得出全局最优是能否采用贪心法的关键所在。
对于能否使用贪心策略,应从理论上予以证明。
下面我们看看另一个问题。
例25:部分背包问题给定一个最大载重量为M的卡车和N种食品,有食盐,白糖,大米等。
已知第i种食品的最多拥有W i公斤,其商品价值为V i元/公斤,编程确定一个装货方案,使得装入卡车中的所有物品总价值最大。
分析:因为每一个物品都可以分割成单位块,单位块的利益越大显然总收益越大,所以它局部最优满足全局最优,可以用贪心法解答,方法如下:先将单位块收益按从大到小进行排列,然后用循环从单位块收益最大的取起,直到不能取为止便得到了最优解。
因此我们非常容易设计出如下算法:问题初始化;{读入数据}按V i从大到小将商品排序;I := 1;repeatif M = 0 then Break; {如果卡车满载则跳出循环}M := M - W i;if M >= 0 then 将第I种商品全部装入卡车else将(M + W i)重量的物品I装入卡车;I := I + 1; {选择下一种商品}until (M <= 0) OR (I >= N)在解决上述问题的过程中,首先根据题设条件,找到了贪心选择标准(V i),并依据这个标准直接逐步去求最优解,这种解题策略被称为贪心法。
Program Exam25;Const Finp='Input.Txt';Fout='Output.Txt';Var N,M :Longint;S :Real;P,W :Array[1..100] Of Integer; Procedure Init; {输出}Var I :Integer;BeginAssign(Input,Finp); Reset(Input);Readln(M,N);For I:=1 To N Do Readln(W[I],P[I]);Close(Input);End;Procedure Sort(L,R:Integer); {按收益值从大到小排序}Var I,J,Y :Integer;X :Real;BeginI:=L; J:=R;X:=P[(L+R) Div 2]/W[(L+R) Div 2];RepeatWhile (I<R)And(P[I]/W[I]>=X) Do Inc(I);While (P[J]/W[J]<=X)And(J>L) Do Dec(J);If I<=J ThenBeginY:=P[I]; P[I]:=P[J]; P[J]:=Y;Y:=W[I]; W[I]:=W[J]; W[J]:=Y;Inc(I); Dec(J);End;Until I>J;If I<R Then Sort(I,R);If L<J Then Sort(L,J);End;Procedure Work;Var I :Integer;BeginSort(1,N);For I:=1 To N DoIf M>=W[I] Then {如果全部可取,则全取}BeginS:=S+P[I]; M:=M-W[I];EndElse {否则取一部分}BeginS:=S+M*(P[I]/W[I]); Break;End;End;Procedure Out; {输出}BeginAssign(Output,Fout); Rewrite(Output);Writeln(S:0:0);Close(Output);End;Begin {主程序}Init;Work;Out;End.因此,利用贪心策略解题,需要解决两个问题:首先,确定问题是否能用贪心策略求解;一般来说,适用于贪心策略求解的问题具有以下特点:①可通过局部的贪心选择来达到问题的全局最优解。
运用贪心策略解题,一般来说需要一步步的进行多次的贪心选择。
在经过一次贪心选择之后,原问题将变成一个相似的,但规模更小的问题,而后的每一步都是当前看似最佳的选择,且每一个选择都仅做一次。
②原问题的最优解包含子问题的最优解,即问题具有最优子结构的性质。
在背包问题中,第一次选择单位质量最大的货物,它是第一个子问题的最优解,第二次选择剩下的货物中单位重量价值最大的货物,同样是第二个子问题的最优解,依次类推。
其次,如何选择一个贪心标准?正确的贪心标准可以得到问题的最优解,在确定采用贪心策略解决问题时,不能随意的判断贪心标准是否正确,尤其不要被表面上看似正确的贪心标准所迷惑。
在得出贪心标准之后应给予严格的数学证明。
下面来看看0-1背包问题。
给定一个最大载重量为M的卡车和N种动物。
已知第i种动物的重量为W i,其最大价值为V i,设定M,W i,V i均为整数,编程确定一个装货方案,使得装入卡车中的所有动物总价值最大。
分析:对于N种动物,要么被装,要么不装,也就是说在满足卡车载重的条件下,如何选择动物,使得动物价值最大的问题。
即确定一组X1,X2,…,Xn, Xi∈{0,1}f(x)=max(∑X i*V i) 其中,∑(X i*W i)≦W从直观上来看,我们可以按照上例一样选择那些价值大,而重量轻的动物。
也就是可以按价值质量比(V i/W i)的大小来进行选择。
可以看出,每做一次选择,都是从剩下的动物中选择那些V i/W i最大的,这种局部最优的选择是否能满足全局最优呢?我们来看看一个简单的例子:设N=3,卡车最大载重量是100,三种动物A、B、C的重量分别是40,50,70,其对应的总价值分别是80、100、150。
情况A:按照上述思路,三种动物的V i/W i分别为2,2,2.14。
显然,我们首先选择动物C,得到价值150,然后任意选择A或B,由于卡车最大载重为100,因此卡车不能装载其他动物。
情况B:不按上述约束条件,直接选择A和B。
可以得到价值80+100=180,卡车装载的重量为40+50=90。
没有超过卡车的实际载重,因此也是一种可行解,显然,这种解比上一种解要优化。