算法思想 -- 贪心算法(1) -- 基本概念及步骤

摘自《算法的乐趣》

贪心算法概述

关键: 问题分解。
在寻找最优解时候,有很多常用的办法,比如说:贪心,分治,回溯,动态规划等等。这些思想有各自的优势,也相互联系,相互区别。

贪心算法,动态规划,和分治法都需要对问题进行分解,定义出问题的最优子结构。

贪心算法是一种比较简便的方法,通过简单的贪心规则,只考虑局部的状况,不考虑局部解对于整体最优解未来的影响。

之所以这样做,是因为有相关人员有个假设:即通过局部利益的最大化,最终能够实现全局利益的最大化或者可以说是接近于全局利益最大化(结果能够达到一定的满意程度)。
或者可以说,问题本身通过分解,具有了适合用贪心算法求解的性质。

概念

最优子结构

最优子结构反映了分解问题的方式,我们再解决问题的时候,都会尝试将问题分解进行解决,产生的子问题,进而会产生局部解(总体解的子结构)。通常而言局部解也不仅只有一个,当局部解是局部最优解,并且该局部最优解是全局最优解的一部分时,我们称子问题的最优解为 最优子结构

最优子结构的性质

问题的最优解由相关子问题的最优解组合而成,而这些子问题可以独立求解。(需要注意这里独立求解的含义:当前最优,不考虑后面的步骤)
最优子结构的形式(或者是否有最优子结构)取决于你分解问题的方式。合理的分解达到的效果是:与最终问题的目标存在紧密的关系。如果分解问题之后却无法导出最终问题的解,那么这种问题分解的方式就是无意义的。
听上去有些抽象,接下来我们举一个例子。

最小生成树问题中,我们的目标是生成一棵树使得边的总和最小

问题分解方式1:按边分。当我们按照边来作为划分依据的时候,边便成了我们主要的研究对象,我们每次选择最小的边,为什么选择最小边?因为min_edge1 +min_edge2 + … <= edge1 + edge2 + … 。第一次我们选择min_edge1,第二次选min_edge2,依次类推,我们不能这么简单的加边,需要在加每条最小边之前进行验证,验证该边的两个节点是否已经在生成的子树中。于是,边构成的最优子结构 导致 最终的解。

问题分解方式2:按点分。在该问题的分解中,我们选择最初的出发点是结点而非边,该结点可看做一棵树。接下来将更多的点包含进来,选择的标准是选取连接该树的最小边。这种方式也同样可以得到最优解。这种方式与之前的方式相比,并不是一开始就将最小的边就加入到树中,而是选择距离已经加入树的结点最近的边以及结点,但是,这同样也能达到方式1的效果。

基本思想

贪婪法求解步骤。

(1)建立对问题精确描述的数学模型,包括定义最优解的模型;
(2)将问题分解为一系列子问题,同时定义子问题的最优解结构;
(3)应用贪心原则确定每个子问题的局部最优解,并根据最优解的模型,用子问题的局部最优解堆叠出全局最优解。

最优解的模型一般都体现了最优解子问题的分解结构和堆叠方式。

体会:

问题与子问题之间的关系,相似性,相互制约。
从问题到子问题,体现分解的特性。
从子问题到问题,体现积累的过程。(对于历史数据的使用)

示例

例 1:(寻找最大值)

 从n  个数中寻找最大值。

这是我们生活中经常见到的问题,大家也都已经习以为常。但是仔细想想找个过程,我们会发现其就是贪心算法的应用。

求解过程:

(1)max(n)= max(n个data)

max(n) 表示 n个数中最大值。

max(data[n]) 表示从n个数中具体进行筛选的过程。

(2)分解成子问题

max(n) = max( max(n-1),data[n] ) 【分解结构 的表现形式】

此处将规模为n的问题转化成 子问题n-1,和子问题1(而子问题1通常是非常容易求得的)

依据上面这条简单的规则,便可不断对子问题 进行进一步的分解。

(3)贪心原则

于是,原则就变成对子问题求最大。

这里的体会:

从原来数据集合中 提取出部分集合,从而达到求解空间变小。(求含(1)四个方程的方程组,与(2)求两个方程组,每个方程组两个方程。两者工作量是完全不一样的,后者大大缩小了求解的空间)
这里将贪心规则设定为:求解部分集合的最大值。(将所分离出来的集合,通过某种方式设定一个标准,使得通过是这个标准最大或者最小,从而达到向整体最优解行进的目的)
贪心规则的选择,以及部分集合的分离是非常需要技巧的。

例2:(图的最小生成树的问题)

G=(V,E)

G为图,V为结点的集合,E为边的集合。

求解过程:

(1)为过程规定状态

为在这个求解的过程中,对处于不同状态的结点与边进行区分,规定 V 中结点与 E 中结点的状态(已加入生成树,未加入生成树)。

V被分成两个集合Vin(已加入),Vout(未加入)。

E被分成两个集合Ein(已加入),Eout(未加入)。

(2)最优解的模型

T = (V, E)

T.V 等于 G.V。

T.E 属于 G.E。

T.E需要最小化,同时确保树中无环。

(体现在:1.筛选时,对于E进行从小到大排列。 2.验证无环,无环则接受)

(3)最优子结构

最小生成树,是否是建立在其更小规模最小生成树上成长起来的?
最小生成树的子树,是否依然是对应子图的最小生成树?
最小生成树 =  子树(最小生成树) + (新结点,新边)
注意此处的“新”字,有一个不满足则不能加入。

(4)贪心原则(以边为例)

最小生成树,从整体上看,可以看做边最小化,同时也要在一定的约束之内(无环)。
上面连个条件决定了,子问题能够堆叠出最终要解决的问题。
通过反正法证明。

参考:
贪心算法之证明要点—-算法导论16.2—5

    原文作者:贪心算法
    原文地址: https://blog.csdn.net/TheSnowBoy_2/article/details/73385652
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞