贪心算法

一. 贪心算法定义

假设一个问题比较复杂,暂时找不到全局最优解,那么咱们能够考虑把原问题拆成几个小问题,分别求每一个小问题的最优解,再把这些“局部最优解”叠起来,就“看成”整个问题的最优解了。java

1.1 怎么理解贪心

在每一步中,选择当前最优而不是全局最优,这就是贪心。算法

1.2 贪心思想和分治思想的区别

贪心和分治都是将问题进行拆分来下降求解的复杂度,不一样的是,分治保证每一个任务相对独立,不考虑最不最优问题; 而贪心子任务间每每存在关联关系,每次取舍之间都选择当前最优。markdown

二. 贪心算法关键步骤

如何知道一个问题是否能够用贪心算法解决呢,分析问题和用贪心解决问题均可以参考一下步骤:cookie

  • 分析问题的最优解
  • 分析子问题的最优解
  • 分析子问题是否可叠加当成问题最优解

三. 经典应用-饼干问题

3.1 问题描述

每一个孩子最多只能给一块饼干,对每一个孩子 i,都有一个胃口值 g[i],这是能让孩子们知足胃口的饼干的最小尺寸;而且每块饼干 j,都有一个尺寸 s[j] 。若是 s[j] >= g[i],咱们能够将这个饼干 j 分配给孩子 i ,这个孩子会获得知足。你的目标是尽量知足越多数量的孩子,并输出这个最大数值。leetcode传送门oop

3.2 根据贪心算法步骤拆解

  • 分析问题最优解

显而易见,知足最多数量的孩子spa

  • 分析子问题的最优解

对于每一个孩子,应该选择能够知足这个孩子的胃口且尺寸最小的饼干code

  • 分析子问题是否可叠加当成问题最优解

从贪心的角度考虑,应该按照孩子的胃口从小到大的顺序依次知足每一个孩子orm

3.3 推导公式

假设有 m 个孩子,胃口值分别是 g1 到 gm,有 n 块饼干,尺寸分别是 s1 到 sn 咱们将两个数列由小到大排序,知足gi <= gi+1 和 sj <= sj+1排序

能够知足第 i 个孩子的胃口的最小的饼干是第 j 块饼干,即 sj是剩下的饼干中知足 sj >= gi的最小值, 最优解是将第 j 块饼干分配给第 i 个孩子leetcode

3.4 代码实现

public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int numOfChildren = g.length, numOfCookies = s.length;
        int count = 0;
        for (int i = 0, j = 0; i < numOfChildren && j < numOfCookies; i++, j++) {
            while (j < numOfCookies && g[i] > s[j]) {
                j++;
            }
            if (j < numOfCookies) {
                count++;
            }
        }
        return count;
    }
复制代码

四. 贪心算法可能存在的问题

4.1 “全局最优”和“局部最优”

平常生活中不少状况,全局最优和局部最优有很大的区别,盲目追求全局最优有可能和预期结果截然不同。

  • 岔路问题

看上去短的路可能岔路多,每次选则最短的路可能会绕一圈

image.png

  • 雪球问题

看上去雪多的路可能路比较短,不如雪粘、路途长的路积累的雪球大

image.png

  • 打车软件离我最近

每次都是离乘客最近的车接单,那么有些地方的乘客可能永远打不到车

image.png

4.2 贪心算法存在的意义

既然贪心算法不能保证全局最优,咱们为何还要须要它呢?

  • 当问题规模很大时,在合理的时间内找到全局最优几乎不可能,这时候咱们每每会倾向于接受局部最优解,由于局部最优解的质量不必定都是差的。
  • 在工程应用领域,有时最优解与局优解的精度相差很小,但为了搜索到全局最优解却须要耗费更长的时间,在权衡计算精度以及时间成本后,决策者每每也能接受局部最优解。

五. 贪心算法应用场景

  • 根据前面的描述,咱们能够知道贪心算法虽然不全局最优,但若是能保证局部最优极大程度趋近于全局最优,那咱们也可使用贪心算法。
  • 若是能够证实决策既不受以前决策的影响,也不影响后续决策,则贪心算法就是肯定的最优解算法。除此以外都不能够保证贪心算法是最优的。

好在前人的经验总结了一些条件能够参考:

  • 问题有限制值和指望值
  • 问题能够经过贪心步骤拆分
  • 求全局最优解的数学模型难以创建或计算量过大
  • 没有太大必要必定要求出全局最优解,“比较优”就能够

常见场景有:背包问题、分糖果、找零钱、区间覆盖等

六. 贪心算法的优缺点

其实在前文中已经都提到了,这里再总结一下。

  • 优势:思路简单、易于实现、处理高效、权衡了最佳解决方案和复杂度。
  • 缺点:须要甄别问题场景,对于局部最优和全局最优差别较大的,不能使用。

七. 如何证实贪心算法能够趋近最优解

证实一个场景能够知足“局部最优极大程度趋近于全局最优”每每难于使用贪心求解。
通常来讲若是一个问题能够转化为拟阵,那就能够贪心求解。但不是全部能够贪心求解的问题都能转化成拟阵。 拟阵的推导涉及一些数学知识,有兴趣能够看看。拟阵与最优问题

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息