贪心算法详解

开通VIP,畅享免费电子书等14项超值服

首页

好书

留言交流

下载APP

联系客服

2024.02.05广东

顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。

当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题等。

在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。

基本思路:

1.建立数学模型来描述问题。

2.把求解的问题分成若干个子问题。

3.对每一子问题求解,得到子问题的局部最优解。

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

实现该算法的过程:

1.从问题的某一初始解出发;

2.while能朝给定总目标前进一步do

3.求出可行解的一个解元素;

4.由所有解元素组合成问题的一个可行解。从问题的某一初始解出发

0-1背包问题

有一个背包,最多能承载150斤的重量,现在有7个物品,重量分别为[35,30,60,50,40,10,25],它们的价值分别为[10,40,30,50,35,40,30],应该如何选择才能使得我们的背包背走最多价值的物品?

把物品一个个的往包里装,要求装入包中的物品总价值最大,要让总价值最大,就可以想到怎么放一个个的物品才能让总的价值最大,因此可以想到如下三种选择物品的方法,即可能的局部最优解:

①:每次都选择价值最高的往包里放。

②:每次都选择重量最小的往包里放。

③:每次都选择单位重量价值最高的往包里放。

①:选择价值最高的,按照制订的规则(价值)进行计算,顺序是:4265。

最终的总重量是:130。

最终的总价值是:165。

②:选择重量最小的,按照制订的规则(重量)进行计算,顺序是:67215。

最终的总重量是:140。

最终的总价值是:155。

可以看到,重量优先是没有价值优先的策略更好。

③:选择单位密度价值最大的,按照制订的规则(单位密度)进行计算,顺序是:62741。

最终的总重量是:150。

最终的总价值是:170。

可以看到,单位密度这个策略比之前的价值策略和重量策略都要好。

单源最大路径问题

给定带权有向图G=(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在要计算从源到所有其它各顶点的最短路长度。

这里路的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。

Dijkstra算法是解单源最短路径问题的贪心算法。

其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。

一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。

初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。

Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist作必要的修改。

一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。

例如,对下图中的有向图,应用Dijkstra算法计算从源顶点1到其它顶点间最短路径的过程列在下表中。

Dijkstra算法的迭代过程:

2、算法的正确性和计算复杂性

(1)贪心选择性质

(2)最优子结构性质

(3)计算复杂性

代码实现(来自于第四个参考链接):

假设你开了间小店,不能电子支付,钱柜里的货币只有25分、10分、5分和1分四种硬币,如果你是售货员且要找给客户41分钱的硬币,如何安排才能找给客人的钱既正确且硬币的个数又最少?

这里需要明确的几个点:

这个步骤可以分解为:

1.找给顾客sum_money=41分钱,可选择的是25分、10分、5分和1分四种硬币。能找25分的,不找10分的原则,初次先找给顾客25分;2.还差顾客sum_money=41-25=16。然后从25分、10分、5分和1分四种硬币选取局部最优的给顾客,也就是选10分的,此时sum_money=16-10=6。重复迭代过程,还需要sum_money=6-5=1,sum_money=1-1=0。至此,顾客收到零钱,交易结束;3.此时41分,分成了1个25,1个10,1个5,1个1,共四枚硬币。按照上述的方式,我们可以得到一个分硬币的最优解,但是再考虑一下同样的分硬币问题:

还是需要找给顾客41分钱,现在的货币只有25分、20分、10分、5分和1分四种硬币;该怎么办?

按照贪心算法的三个步骤:

可以根据这种策略得到一个解,但是该问题是不是最优的解?显然并不是的,因为如果给他2个20分,加一个1分,三枚硬币就可以了。

所以这里就突出了贪心算法的一个问题:不从总体上考虑其它可能情况,每次选取局部最优解,不再进行回溯处理,所以很少情况下得到最优解。

贪心算法三个核心问题

第一个问题:为什么不直接求全局最优解

1、原问题复杂度过高;

2、求全局最优解的数学模型难以建立;

3、求全局最优解的计算量过大;

4、没有太大必要一定要求出全局最优解,“比较优”就可以。

第二个问题:如何把原问题分解成子问题?

1、按串行任务分

2、按规模递减分

规模较大的复杂问题,可以借助递归思想(见第2课),分解成一个规模小一点点的问题,循环解决,当最后一步的求解完成后就得到了所谓的“全局最优解”。

3、按并行任务分

这种问题的任务不分先后,可能是并行的,可以分别求解后,再按一定的规则(比如某种配比公式)将其组合后得到最终解。

第三个问题:如何知道贪心算法结果逼近了全局最优值?

这个问题是不能量化判断的,正是因为全局最优值不能够知道,所以才求的局部最优值。追求过程需要考虑以下几个问题:

成本

速度

计算量是否过大,计算速度能否满足要求。

价值

得到了最优解与次优解是否真的有那么大的差别,还是说差别可以忽略。

THE END
1.刷题29天贪心算法那么又要贪心了,局部最优:取candyVec[i + 1] + 1 和 candyVec[i] 最大的糖果数量,保证第i个小孩的糖果数量既大于左边的也大于右边的。全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。 c++ classSolution{public:intcandy(vector<int>&ratings){vector<int>candyVec(ratings.size(),1);//1从前往后https://zhuanlan.zhihu.com/p/11941030486
2.算法第二十五天贪心贪心算法的核心思想就是,局部最优推出全局最优。 优先大饼干满足大胃口,或者小饼干满足小胃口,都可以完成目标。 376. 摆动序列 classSolution{publicintwiggleMaxLength(int[]nums){if(nums.length<=1){return1;}intpreDiff=0;intcurDiff=0;intresult=1;// 因为默认最后面是一个峰值for(inti=0;i<nums.lengthhttps://www.jianshu.com/p/89ecffe0a5ec
3.今日热搜丨贪心算法贪心的意思 在于在作出选择时,每次都要选择对自身 最为有利的结果,保证自身利益的最大化。贪心算法就是利用 这种贪心思想而得出一种算法。关于贪心算法,一起来了解!什么是贪心算法 贪心算法(greedy algorithm ,又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,该算法在每个https://baijiahao.baidu.com/s?id=1742021741621560533&wfr=spider&for=pc
4.《趣学算法》第二章贪心算法源代码zengpingfun贪心算法相关代码实现 1、加勒比海盗船——最优装载问题 2、阿里巴巴与四十大盗——背包问题 3、高级钟点秘书——会议安排 4、一场说走就走的旅行——最短路径 5、神秘电报密码——哈夫曼编码 6、沟通无限校园网——最小生成树 贪心算法相关代码实现 https://www.cnblogs.com/self-confidence/p/13603491.html
5.js贪心算法钱币找零问题代码实例javascript技巧这篇文章主要介绍了js贪心算法 钱币找零问题代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下GPT4.0+Midjourney绘画+国内大模型 会员永久免费使用!【 如果你想靠AI翻身,你先需要一个靠谱的工具!】给定一组硬币的面额,以及要找零的钱数,计算出符合找零钱数https://www.jb51.net/article/169824.htm
6.免费贪心算法详解与实际使用示例代码贪心算法资源算法设计方法:系统性地介绍了贪心算法的设计原则、证明技巧和实现注意事项,帮助读者更好地理解和应用贪心策略。扩展内容:涵盖了贪心算法与动态规划、分治等其他算法的结合应用,以及随机化贪心、并行贪心等进阶主题。 这份教程采用循序渐进的方式,从理论到实践,从基础到进阶,配合丰富的代码示例和详细的解释,适合想要深入https://download.csdn.net/download/weixin_55344375/89997619
7.贪恋算法(贪心算法)的一些例题及部分matlab代码贪恋算法(贪心算法)的一些例题及部分matlab代码-经管之家官网! 贪恋算法(贪心算法)的一些例题及部分matlab代码 人大经济论坛-经管之家:分享大学、考研、论文、会计、留学、数据、经济学、金融学、管理学、统计学、博弈论、统计年鉴、行业分析包括等相关资源。https://bbs.pinggu.org/jg/qikan_qikanku_8585085_1.html
8.代码随想录投稿视频代码随想录视频分享贪心算法的巧妙需要慢慢体会!LeetCode:53. 最大子序和 4.9万2023-1-16 22:57 6.2万2023-1-13 12:39 8万2023-1-11 4.4万2023-1-9 16:49 19:18 4.8万2023-1-6 17:15 16:28 登录后你可以: 免费看高清视频 多端同步播放记录 发表弹幕/评论 https://space.bilibili.com/525438321/video
9.贪心算法WOODENSTICKS实例代码贪心算法 WOODEN STICKS 实例代码 Problem Description There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to https://www.xiuzhanwang.com/a1/Cyuyan/4505.html
10.java贪心算法换硬币mob64ca12eaf194的技术博客换硬币问题是经典的动态规划题目,也是贪心算法的一个重要应用。简单来说,换硬币问题是指在给定的面额和数量的情况下,如何用最少的硬币数量来凑成一个特定的金额。本文将深入探讨这一问题,并通过 Java 代码示例帮助读者理解贪心算法在这一问题中的应用。 https://blog.51cto.com/u_16213409/12864082
11.2020届计算机科学方向毕业设计(论文)阶段性汇报代码算法自动分类的研究 课题进展总体较顺利。于收集数据方面,在APEX实验室的帮助下,获得了7千余例HDU和POJ上的源代码及其对应的标签,大大加快了课题的进展。于设计算法方面,基于目前现有的研究都依靠语法树、控制流图和数据流图进行分析的现状,初步设计了从源代码直接入手进行分类的软件。目前的F1分数约在70左右,正https://zhiyuan.sjtu.edu.cn/html/zhiyuan/announcement_view.php?id=3709
12.C++算法集锦(14):贪心算法腾讯云开发者社区代码实现 跳跃游戏 II 思路 贪心算法 贪心算法可以理解为一种特殊的动态规划为题,拥有一些更加特殊的性质,可以进一步降低动态规划算法的时间复杂度。 来看几道题目熟悉一下这种“不断寻求局部最优”的算法。 跳跃游戏 I 输入一个非负整数数组nums,数组元素nums[i]表示的是:如果你站在位置 i ,最多能够往前跳几步https://cloud.tencent.com/developer/article/1879118
13.贪心算法WOODENSTICKS实例代码贪心算法 WOODEN STICKS 实例代码,需要的朋友可以参考一下 贪心算法 WOODEN STICKS2020-09-05 上传大小:37KB 所需:18积分/C币 用贪心算法解单源最短路径问题 用贪心算法解单源最短路径问题 明确单源最短路径问题的概念;利用贪心算法解决单源最短路径问题;并通过本例熟悉贪心算法在程序设计中的应用方法。 https://www.iteye.com/resource/weixin_38720756-12814957