第4章 贪心算法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2
【渴婴】
有一个非常渴的、但很聪明的小婴儿。她可能得到的东 西包括:一杯水、一小罐牛奶、多罐其它不同种类的 果汁……。即婴儿可能得到n种不同口味的饮料。
根据以前对这n种饮料的不同体验,这个婴儿知道其中 某种饮料更适合自己的胃口,因此婴儿采用如下方法 为每一种饮料赋予一个满意度值,即Si作为满意度赋 予第i种饮料。 通常,这个婴儿都会尽量饮用具有最大满意度的饮料来 最大限度地满足她解渴地需要,但不幸地是:她最满 意地饮料有时并没有足够地量来满足这个婴儿解渴地 需要。 3
对于一个具体问题,要确定它是否具有贪心选择性质, 必须证明每一步所作的贪心选择最终导致问题的整体最 23 优解。
4.2 贪心算法的基本要素
2、最优子结构性质
当一个问题的最优解包含其子问题的最优 解时,称此问题具有最优子结构性质。问题的 最优子结构性质是该问题可用动态规划算法或
贪心算法求解的关键特征。
20
4.1 活动安排问题
和活动安排问题类似的是“区间相 交问题”。
【区间相交问题】:给定x轴上n个 闭区间。去掉尽可能少的闭区间, 使剩下的闭区间都不相交。 算法:这个问题和“活动安排问题” 类似。每次选取右端点坐标最小的 闭区间,并将与其相交的闭区间删 去!
21
4.2 贪心算法的基本要素
本节着重讨论可以用贪心算法求解的问题 的一般特征。 对于一个具体的问题,怎么知道是否可用 贪心算法解此问题,以及能否得到问题的最 优解呢?这个问题很难给予肯定的回答。 但是,从许多可以用贪心算法求解的问题 中看到这类问题一般具有2个重要的性质: 贪心选择性质和最优子结构性质。
首先证明最优解A的构成: 前k步和剩下活动的最优
解;再根据剩下活动的最
优解和前k步一样,又包
含剩下活动的第一个的最
优解,即第k+1个。
19
4.1 活动安排问题
思考:其它的贪心选择方案:
(1)选择具有最短时段的相容活动 (2)选择覆盖未选择活动最少的相 容活动
(1)(2)都无法获得最优解。 如右图所示活动系列: 最优解{1,2,3,4} (1)选择为{1,4,5} (2)的初选5,5一旦选中,最多只能再选两个
且希望用最少数目的钱币找给小孩。
解:售货员每次加入一种钱币,并采用的贪婪准则是:
每次选择的某种钱币面值尽可能大,所需张数尽可
能少,但同时需保证解法的可行性(即,所给的零 钱等于要找的零钱数,不多给不少给)。
5
贪心算法 形象模型
最高峰 次高峰 小山峰 小山峰 小山峰
小山峰
6
顾名思义,贪心算法总是作出在当前看来最 好的选择。 也就是说贪心算法并不从整体最优考虑, 它所作出的选择只是在某种意义上的局部最优 选择。 当然,希望贪心算法得到的最终结果也是 使用贪心法要解决的问题: 整体最优的。虽然贪心算法不能对所有问题都 是否可以得到最优解? 得到整体最优解,但对许多问题它能产生整体 最优解。如单源最短路经问题,最小生成树问 不能得到最优解,贪心解与最优解的 题等。在一些情况下,即使贪心算法不能得到 误差估计 整体最优解,其最终结果却是最优解的很好近 似。
25
4.2 贪心算法的基本要素
0-1背包问题:
给定n种物品和一个背包。物品i的重量是Wi, 其价值为Vi,背包的容量为C。应如何选择装入背 包的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i只有 2种选择,即装入背包或不装入背包。不能将物品 i装入背包多次,也不能只装入部分的物品i。
4.1 活动安排问题
下面给出解活动安排问题的贪心算法GreedySelector :
template<class Type>
void GreedySelector(int n, Type s[], Type f[], bool A[]) { A[1]=true; int j=1;
for (int i=2;i<=n;i++) {
假设:物品已依单位重量价值递减排序来编号, 若 C≥w1(若C<w1也同理可证),存在背包问题的一个最 优解X=(x1,…,xn),且0≤x1<1,这里x1≠1表示最优解 X并不满足贪心选择。 证: 由0≤x1<1,那么最优解除x1外被选入物品最小编号 为k,k=min{ i | xi>0,2≤i ≤n},令Y=(y1,…,yn) 为最优 解X=(x1,…,xn)拿掉物品k(若物品k不够则继续拿后继 物品k+1等)的全部或部分,换上与拿掉那部分等重量 物品1,其余物品的选择都不变。由于是等重替换,因 此Y解和X解等重量,都是可行解。另外这种替换并不 减小总价值,因为等重的物品1比物品k有更高价值。 X解是最优解,因此Y解也是满足贪心选择性质的最优 解。 30
x
n
n
i 1
不过,若 a i t ,则不可能找到问题的求解方案,因 i 1 为即使喝光了所有的饮料也不能使婴儿解渴。 4
i 1
i
t 0 xi a i
【找零钱】
一个小孩买糖,付了1美元,假设需要找给小孩67
美分。而提供了如下数目不限的面值钱币:25美分
(Quarters)、10美分(Dimes)、5美分(Nickels)及1 美分(Pennies)。现在问题就是:保证找回67美分,
22
4.2 贪心算法的基本要素
1、贪心选择性质
所谓贪心选择性质是指所求问题的整体最优解可以 通过一系列局部最优的选择,即贪心选择来达到。这是 贪心算法可行的第一个基本要素,也是贪心算法与动态 规划算法的主要区别。
动态规划算法通常以自底向上的方式解各子问题,而 贪心算法则通常以自顶向下的方式进行,以迭代的方式 作出相继的贪心选择,每作一次贪心选择就将所求问题 简化为规模更小的子问题。
9
4.1 活动安排问题
贪心算法:活动i在相容活动集合A中,当且仅当A[i]的值为
true。用变量j记录最近一次加入A的活动序号。
将各活动的起始时间和结束时间存储于数组s和数组f中, 按照结束时间的非递减顺序排列,即按照f1≤f2≤…≤fn排列,可 以用O(nlogn)的时间进行排列。 一开始选择活动1,j初始化为1。然后依次检查活动i是否与当 前已选择的所有活动相容。 相容则将活动i加入到相容活动集合A中,否则不选择活动i,而 继续检查下一活动与集合A中活动的相容性。 由于fj总是当前集合A中所有活动的最大结束时间,故活动i与 当前集合A中所有活动相容的充分必要条件是:si≥fj,若活动i与 活动j相容,则将i成为最新加入集合A中的活动,并取代活动j的 10 位置。
第4章 贪心算法
1
学习要点
贪心算法的基本思想
贪心算法的基本要素
(1)最优子结构性质 (2)贪心选择性质
贪心算法与动态规划算法的差异 正确性的证明
难!
范例学习贪心设计策略
(1)活动安排问题; (4)单源最短路径; (2)最优装载问题; (5)最小生成树; (3)哈夫曼编码; (6)多机调度问题。
7
4.1 活动安排问题
活动安排问题就是要在所给的活动 集合中选出最大的相容活动子集合,是 可以用贪心算法有效求解的很好例子。 该问题要求高效地安排一系列争用某一 公共资源的活动。贪心算法提供了一个 简单、漂亮的方法使得尽可能多的活动 能兼容地使用公共资源。
8
4.1 活动安排问题
设有n个活动的集合E={1,2,…,n},其中 每个活动都要求使用同一资源,如演讲会场 等,而在同一时间内只有一个活动能使用这 一资源。每个活动i都有一个要求使用该资源 的起始时间si和一个结束时间fi,且si <fi 。如果 活动安排问题:就是要在所 选择了活动i,则它在半开时间区间[si, fi)内占 给的活动集合内选出最大的 相容活动子集合。 用资源。若区间[si, fi)与区间[sj, fj)不相交,则 称活动i与活动j是相容的。也就是说,当si≥fj 或sj≥fi时,活动i与活动j相容。
26
4.2 贪心算法的基本要素
背包问题:
与0-1背包问题类似,所不同的是在选择物品i
装入背包时,可以选择物品i的一部分,而不
一定要全部装入背包,1≤i≤n。 这2类问题都具有最优子结构性质,看似相似, 但却是两种不同难易度的问题。
背包问题可以用贪心算法求解,而0-1背包问 题却不能用贪心算法求解。
【渴婴】
问题模型定义:设ai为第i种饮料的总量(假设以毫升 为单位),而婴儿需要t毫升的饮料来解渴,那么需 要饮用n种不同的饮料各多少才能满足婴儿解渴的需 求呢?
设各种饮料的满意度Si已知,令xi为将要饮用的第i种 饮料的量,那么需要解决的问题是:求解一组实数向 n 量xi(1≤i≤n),使得: S i xi 最大,并满足:
算法greedySelector的效率极高。当输入的活动 已按结束时间的非减序排列,算法只需O(n)的时间安 排n个活动,使最多的活动能相容地使用公共资源。 如果所给出的活动未按非减序排列,可以用O(nlogn) 的时间重排。 12
4.1 活动安排问题
例:设待安排的11个活动的开始时间和结束 时间按结束时间的非减序排列如下:
24
4.2 贪心算法的基本要素
3、贪心算法与动态规划算法的差异
贪心算法和动态规划算法都要求问题具有最优 子结构性质,这是2类算法的一个共同点。但是, 对于具有最优子结构的问题应该选用贪心算法还是 动态规划算法求解?是否能用动态规划算法求解的
问题也能用贪心算法求解?下面研究2个经典的组合
优化问题,并以此说明贪心算法与动态规划算法的 主要差别。
14
4.1 活动安排问题
若被检查的活动i的开始时间Si小于最近选 择的活动j的结束时间fi,则不选择活动i,否 则选择活动i加入集合A中。
贪心算法并不总能求得问题的整体最优解。 但对于活动安排问题,贪心算法 greedySelector却总能求得的整体最优解,即 它最终所确定的相容活napsack的 主要计算时间在于将 各种物品依其单位重 量的价值从大到小排 序。因此,算法的计 算时间上界为 O(nlogn)。 为了证明算法的 正确性,还必须证明 背包问题具有贪心选 择性质。
4.2 贪心算法的基本要素
证明:背包问题具有贪心选择性质: 根据背包问题的描述,可知背包一定会被装满。
27
4.2 贪心算法的基本要素
用贪心算法解背包问题的基本步骤:
首先计算每种物品单位重量的价值Vi/Wi,然后, 依贪心选择策略,将尽可能多的单位重量价值最高 的物品装入背包。若将这种物品全部装入背包后,
背包内的物品总重量未超过C,则选择单位重量价值
次高的物品并尽可能多地装入背包。依此策略一直 地进行下去,直到背包装满为止。 具体算法可描述如下页:
这个结论可以用数学归纳法证明。(书 P104-105)
15
4.1 活动安排问题
16
4.1 活动安排问题
因为ik+1活动是S’中具有 最早完成时间的, 因此根据归纳假设,存在 S’的最优解B’包含ik+1 这里仅写 出证明思 路 详细证明 过程见后 续页 17
4.1 活动安排问题
18
4.1 活动安排问题
if (s[i]>=f[j]) { A[i]=true; j=i; } else A[i]=false;
各活动的起始时间和结 束时间存储于数组s和f 中且按结束时间的非减 序排列
11
}
}
4.1 活动安排问题
由于输入的活动以其完成时间的非减序排列,所 以算法greedySelector每次总是选择具有最早完成 时间的相容活动加入集合A中。直观上,按这种方法 选择相容活动为未安排活动留下尽可能多的时间。也 就是说,该算法的贪心选择的意义是使剩余的可安 排时间段极大化,以便安排尽可能多的相容活动。
28
4.2 贪心算法的基本要素
void Knapsack(int n,float M,float 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]; }
i
1
2 3
3 0
4 5
5 3
6 5
7 6
8 8
9 8
10 11 2 12
S[i] 1
f[i]
4
5
6
7
8
9
10 11 12 13 14
13
4.1 活动安排问题
算法greedySelector 的计算过程如左图所示。 图中每行相应于算法的 一次迭代。 阴影长条表示的活动 是已选入集合A的活动, 而空白长条表示的活动 是当前正在检查相容性 的活动。
相关文档
最新文档