多一些Aha Time,发现技术的美妙🍺|

啊原来是这样呀

园龄:8年3个月粉丝:3关注:9

【算法基础】3.五大算法之贪心算法

参考资料

贪心算法及常见例子https://blog.csdn.net/m0_37741420/article/details/107402239

 

直观理解

贪心算法是通过局部最优解来达到全局最优解

指在对问题求解时,总是做出在当前看来是最好的选择。也就是说不从整体最优上加以考虑,算法得到的结果是在某种意义上的局部最优解

 

例子先行

在某个地方需要举办不同的活动,每个活动要花费不同时间(起止时间不同),问怎样安排,可以安排尽量多的活动?此问题之所以可以用贪心算法解决,是因为下个活动的选择可以只取决于上个活动结束时间,而不必从全局考虑。 

已经按结束时间排好序的活动列表,开始时间和结束时间如下:

活动1234567891011
开始时间 1 3 0 5 3 5 6 8 8 2 12
结束时间 4 5 6 7 8 9 10 11 12 13 14

因为必须在前一个活动结束之后,才能开始下一个活动,因此先对活动的结束时间进行排序,然后按顺序确定下一个可用的启动时间。
活动选择问题的迭代解法,示例代码如下

迭代版:

复制代码
 1 static List<int> activityChoice(int[] startTime, int[] endTime)
 2 {
 3     List<int> list = new List<int>();
 4     /*因为活动已经按结束时间进行过升序排列,所以要默认选中第一个活动*/
 5     list.add(0);
 6 
 7     /*当前开始活动的结束时间*/
 8     int curTime = endTime[0];
 9     for (int i = 1; i < endTime.length; i++)
10     {
11         /*如果目前的活动的开始时间>=之前选择的活动的结束时间,则选取该活动,更新当前时间*/
12         if (startTime[i] >= curTime)
13         {
14             list.add(i);
15             curTime = endTime[i];
16         }
17     }
18     return list;
19 }
复制代码

 递归版,要注意带入当前已经举办的最后一个活动的序号

复制代码
 1     static List<Integer> acivitySelector(int[] startTime, int[] endTime, int i, int n,List<Integer> list) {
 2         //因为活动已经按结束时间进行过升序排列,所以要默认选中第一个活动
 3         if(i==0){
 4             list.add(i);
 5         }
 6 
 7         int j=i+1;
 8         /*此处的循环是过滤掉不符合要求的活动*/
 9         while (j<=n && endTime[i]>startTime[j]){
10             j++;
11         }
12         //找到一个满足f[i]<=s[j]的活动,添加到list
13         if (j<=n) {
14             //j对应活动的编号
15             list.add(j);
16 /*更新一下当前活动j,然后继续向后找满足条件的活动*/ 17 acivitySelector(startTime, endTime, j, n,list); 18 } 19 return list; 20 }
复制代码

 

 

总结提炼

1.适用场景

(1)贪心性质:一个问题的整体最优解可通过一系列局部的最优解的选择达到,并且每次的选择可以依赖以前作出的选择,但不依赖于后面要作出的选择;

(2)最优子结构:当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质;

2.使用步骤

在使用贪心算法时,待选择的因素先处理为有序的。在该前提下,才可能做出对当前最优的选择

1 while(约束条件成立){
2   选择当前最优解,记录并累积到最后的解中
3   if(当前最优解使用完毕)
4     当前最优解 = 下一个最优解
5 }

3.缺陷

是局部最优而不是全局最优

比如钱币找零问题,假如有15元,需要用11、5、1三种面额的钱币来表示,如果用贪心算法来选择的话,会从11开始选择,这样就会选出11+1+1+1+1的方案,用5张钱币来表示,但实际上,用5+5+5的方案,使用的钱币更少,此时贪心方案就选不出全局最优解

 

拓展方向

(1)活动选择问题(上方例子)
(2)钱币找零问题,先用大额后用小额
(3)再论背包问题,容量有限,先放价值高的再放价值低的
(4)小船过河问题
(5)区间覆盖问题

本文作者:啊原来是这样呀

本文链接:https://www.cnblogs.com/OhOfCourse/p/16897026.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   啊原来是这样呀  阅读(132)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起