第4章 贪心算法(0-算法思想)
第4章贪心算法习题(免费阅读)
算法实现题4-5 程序存储问题
数据输入:
第一行是2 个正整数,分别表示文件个数n和磁带的长 度L。接下来的1 行中,有n个正整数,表示程序存放在磁 带上的长度。
结果输出: 最多可以存储的程序数。
输入示例
6 50
2 3 13 8 80 20 输出示例
5
i 012345
x 2 3 13 8 80 20 7
3
算法实现题4-5 程序存储问题
问题描述: 设有n 个程序{1,2,…, n }要存放在长度为L的磁带上。
程序i存放在磁带上的长度是 li,1 ≤ i ≤ n。 程序存储问题要求确定这n 个程序在磁带上的一个
存储方案,使得能够在磁带上存储尽可能多的程序。 编程任务:
对于给定的n个程序存放在磁带上的长度,编程计 算磁带上最多可以存储的程序数。
532.00
10
算法实现题4-6 最优服务次序问题
double greedy( vector<int> x) {
int i,n=x.size(); sort(x.begin(),x.end()); for(i=1;i<n;++i)
x[i] += x[i-1]; double t=0; for(i=0;i<n;++i) t+=x[i]; t /= n;
算法实现题4-5 程序存储问题
int greedy( vector<int> x, int m){
int i=0, sum=0, n=x.size();
sort(x.begin(),x.end());
while(i
if(sum <= m) i++;
贪婪算法思想及其应用[5篇模版]
贪婪算法思想及其应用[5篇模版]第一篇:贪婪算法思想及其应用贪婪算法思想及其应用摘要:贪婪算法也称作贪心算法,它没有固定的算法框架,算法设计的关键是贪婪策略的选择,并且所选的贪婪策略要具有无后向性。
关键词:贪婪策略,无后向性,最优正文:一.贪婪算法的定义:贪婪算法又叫登山法,它的根本思想是逐步到达山顶,即逐步获得最优解,是解决最优化问题时的一种简单但适用范围有限的策略。
二.贪婪算法思想:贪婪算法采用逐步构造最优解的方法,即在每个阶段,都选择一个看上去最优的策略(在一定的标准下)。
策略一旦选择就不可再更改,贪婪决策的依据称为贪婪准则,也就是从问题的某一个初始解出发并逐步逼近给定的目标,以尽可能快的要求得到更好的解。
而且它在设计时没有固定的框架,关键在于贪婪策略的选择。
但要注意的是选择的贪婪策略要具有无后向性,即某阶段状态一旦确定下来后,不受这个状态以后的决策的影响,也就是说某状态以后的过程不会影响以前的状态,只与当前状态有关。
三.贪婪算法的优缺点:贪婪算法的优点在于在求解问题的每一步它都是选择最优解,这样算法就容易实现也易于理解,同时也提高了效率并节省了时间。
然而贪婪算法的缺点也是不容忽视的,由于它采取逐步获得最优解的方法而不从整体最优上加以考虑,它所做出的仅是在某种意义上的局部最优解。
因此贪婪算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题它都能得出整体最优解或者是整体最优解的近似解。
四.实例参考:下面就列举用贪婪算法成功得出问题最优解的例子:例:一个小孩拿着一美元去商店买糖果,花了33美分,售货员需要找回67美分给小孩,而美分的面值有25,10,5,1这几种。
问题是售货员找个小孩的钱币的个数应是最少的,但同时要满足67美分这个条件。
分析:选择硬币时所采用的贪婪准则如下:每一次都选择面值最大的货币来凑足要找的零钱总数,但前提是不能超出要找的67美分。
解:我们用贪婪算法来处理这个问题,首先我们肯定会选择面值为25的货币,这样的货币我们需要两枚,然后我们依据贪婪准则选择面值为10的货币,这样的货币我们需要一枚,接着继续选择面值为5的货币一枚和面值为1的货币两枚。
贪心法
贪心法贪心法(Greedy Approach)又称贪婪法, 在对问题求解时,总是做出在当前看来是最好的选择,或者说是:总是作出在当前看来最好的选择。
也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
当然,希望贪心算法得到的最终结果也是整体最优的。
虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。
如单源最短路经问题,最小生成树问题等。
在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。
贪心法的设计思想当一个问题具有以下的性质时可以用贪心算法求解:每一步的局部最优解,同事也说整个问题的最优解。
如果一个问题可以用贪心算法解决,那么贪心通常是解决这个问题的最好的方法。
贪婪算法一般比其他方法例如动态规划更有效。
但是贪婪算法不能总是被应用。
例如,部分背包问题可以使用贪心解决,但是不能解决0-1背包问题。
贪婪算法有时也用用来得到一个近似优化问题。
例如,旅行商问题是一个NP难问题。
贪婪选择这个问题是选择最近的并且从当前城市每一步。
这个解决方案并不总是产生最好的最优解,但可以用来得到一个近似最优解。
让我们考虑一下任务选择的贪婪算法的问题, 作为我们的第一个例子。
问题:给出n个任务和每个任务的开始和结束时间。
找出可以完成的任务的最大数量,在同一时刻只能做一个任务。
例子:下面的6个任务:start[] = {1, 3, 0, 5, 8, 5};finish[] = {2, 4, 6, 7, 9, 9};最多可完成的任务是:{0, 1, 3, 4}贪婪的选择是总是选择下一个任务的完成时间至少在剩下的任务和开始时间大于或等于以前选择任务的完成时间。
我们可以根据他们的任务完成时间,以便我们总是认为下一个任务是最小完成时间的任务。
1)按照完成时间对任务排序2)选择第一个任务排序数组元素和打印。
3) 继续以下剩余的任务排序数组。
……a)如果这一任务的开始时间大于先前选择任务的完成时间然后选择这个任务和打印。
算法设计与分析第04章 贪心算法PPT课件
4.1 活动安排问题
若被检查的活动i的开始时间Si小于最近选择的活动j 的结束时间fi,则不选择活动i,否则选择活动i加入集 合A中。
贪心算法并不总能求得问题的整体最优解。但对 于活动安排问题,贪心算法greedySelector却总能求 得的整体最优解,即它最终所确定的相容活动集合A的 规模最大。这个结论可以用数学归纳法证明。
•}
6
4.1 活动安排问题
由于输入的活动以其完成时间的非减序排列,所 以算法greedySelector每次总是选择具有最早完成 时间的相容活动加入集合A中。直观上,按这种方法 选择相容活动为未安排活动留下尽可能多的时间。也 就是说,该算法的贪心选择的意义是使剩余的可安排 时间段极大化,以便安排尽可能多的相容活动。
算法greedySelector的效率极高。当输入的活 动已按结束时间的非减序排列,算法只需O(n)的时间 安排n个活动,使最多的活动能相容地使用公共资源。 如果所给出的活动未按非减序排列,可以用O(nlogn) 的时间重排。
7
4.1 活动安排问题
例:设待安排的11个活动的开始时间和结束时间按结 束时间的非减序排列如下:
13
4.2 贪心算法的基本要素
3.贪心算法与动态规划算法的差异
贪心算法和动态规划算法都要求问题具有最优子结构 性质,这是2类算法的一个共同点。但是,对于具有最 优子结构的问题应该选用贪心算法还是动态规划算法 求解?是否能用动态规划算法求解的问题也能用贪心算 法求解?下面研究2个经典的组合优化问题,并以此说 明贪心算法与动态规划算法的主要差别。
11
4.2 贪心算法的基本要素
1.贪心选择性质
所谓贪心选择性质是指所求问题的整体最优解可以通 过一系列局部最优的选择,即贪心选择来达到。这是 贪心算法可行的第一个基本要素,也是贪心算法与动 态规划算法的主要区别。
贪心算法
有人说贪心算法是最简单的算法,原因很简单:你我其实都很贪,根本不用学就知道怎么贪。
有人说贪心算法是最复杂的算法,原因也很简单:这世上会贪的人太多了,那轮到你我的份?贪心算法详解贪心算法思想:顾名思义,贪心算法总是作出在当前看来最好的选择。
也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
当然,希望贪心算法得到的最终结果也是整体最优的。
虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。
如单源最短路经问题,最小生成树问题等。
在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。
贪心算法的基本要素:1.贪心选择性质。
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。
这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。
动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。
对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。
2. 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。
问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。
贪心算法的基本思路:从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。
当达到算法中的某一步不能再继续前进时,算法停止。
该算法存在问题:1. 不能保证求得的最后解是最佳的;2. 不能用来求最大或最小解问题;3. 只能求满足某些约束条件的可行解的范围。
实现该算法的过程:从问题的某一初始解出发;while 能朝给定总目标前进一步do求出可行解的一个解元素;由所有解元素组合成问题的一个可行解;用背包问题来介绍贪心算法:背包问题:有一个背包,背包容量是M=150。
计算机算法设计与分析 王晓东第 版
School of Computer and Communication Engineer
19
Fun Time
考虑如下活动集合 S:
i 1 2 3 4 5 6 7 8 9 10 11 si 1 3 0 5 3 5 6 8 8 2 12 fi 4 5 6 7 9 9 10 11 12 14 16
• 子集 {a3, a9, a11} 为一相容活动集合 • 计算最大相容活动集合?
最优解.
School of Computer and Communication Engineer
14
0/1 背包问题动态规划求解
• 贪心选择无法保证最终能将背包装满, 部分闲置的背 包空间使物品单位重量的价值发生变化
• 应比较选择该物品和不选择该物品所导致的最终方 案, 然后再作出最好选择(重叠子问题)
为了选择最多的相容活动, 每次选择 fi 最小的相容活 动, 即, 使以后可选更多的活动—“贪心(Greedy)”.
School of Computer and Communication Engineer
26
活动选择问题贪心算法
考虑如下活动集合 S: i 1 2 3 4 5 6 7 8 9 10 11 si 1 3 0 5 3 5 6 8 8 2 12 fi 4 5 6 7 9 9 10 11 12 14 16
• 贪心算法: 每一步做出一个选择, 该选择不依赖于子 问题的解
* 一个问题是否具有贪心选择性需要证明
School of Computer and Communication Engineer
7
最优子结构
定义 2. 若一个优化问题的最优解包括它的子问题的最 优解, 则称其具有最优子结构. • 动态规划: 最优子结构, 子问题重叠性 • 贪心算法: 最优子结构, 贪心选择性
(算法分析与设计)2.贪心算法
n
wixi
vixi
28.2
31
31.5
...
i1
[算法思路]1).将各物体按单位价值由高到低排序.
2).取价值最高者放入背包.
3).计算背包剩余空间.
4).在剩余物体中取价值最高者放入背包.
若背包剩余容量=0或物体全部装入背包为止
算法设计与分析 > 贪心算法
背包问题的贪心算法
print tour, cost }
*该算法不能求得最优解. 算法的最坏时间复杂性为O(n2)
该问题为NP难问题.
算法设计与分析 > 贪心算法
4.7 多机调度问题
问题:设有n个独立的作业{1, 2, …, n}, 由m台相同的机器进行加工 处理. 作业i所需时间为t i. 约定:任何作业可以在任何一台机器上 加工处理, 但未完工前不允许中断处理,任何作业不能拆分成更小 的子作业。要求给出一种作业调度方案,使所给的n 个作业在尽 可能短的时间内 由m台机器加工处理完成。 该问题为NP完全问题.
A complete tree is filled from the left: • all the leaves are on • the same level or • two adjacent ones and • all nodes at the lowest level are as far to the left as possible.
最大相容活动子集(1, 4, 8, 11), 也可表示为等长n元数组:(1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1)
算法设计与分析 > 贪心算法
活动安排问题贪心算法
template< class Type > void GreedySelector(int n, Type s[ ], Type f[ ], bool A[] ) { A[ 1 ] = true;
算法设计与分析课件--贪心法-最小生成树问题
6
4.5 最小生成树问题
◼ Prim算法思想:
❖Prim算法利用了最小生成树的上述性质。 ❖ 算法的关键是如何找出连接U和V-U所有边中的权值 最小的边(u, v),并将v加入到U中。循环执行上述操作, 直至U=V为止。
7
4.5 最小生成树问题
◼ Prim算法设计:
❖ 设G=(V,E)是具有n个结点的无向连通带权图;设最 小生成树T=(U,TE),算法结束时U=V,TE包含于E
点的无向连通带权图,U是
V的一个非空子集。最小生
成树的一个很重要的性质:
✓ (u, v)是一条具有最小权 值 的 边 , 其 中 u∈U , v∈V-U,则必存在一棵包
假设最小生成树T不包括(u,v)。 将(u,v)添加到T上产生回路, 将回路中另外一条边(u’,v’)去 掉得到另外一个树T’
含 边 (u , v) 的 最 小 生 成 树 。
◼ Prim算法的求解示例:
18
4.5 最小生成树问题
◼ Prim算法的求解示例:
19
4.5 最小生成树问题
◼ Prim算法的求解示例:
20
4.5 最小生成树问题
◼ Prim算法的求解示例:
21
4.5 最小生成树问题
◼ Prim算法的求解示例:
22
4.5 最小生成树问题
◼ Prim算法的求解示例:
◼ Prim算法空间复杂性:
❖定义了辅助变量Q,其占用空间为|V|,从而空间复 杂度为O(|V|)。
27
4.5 最小生成树问题
◼ Prim算法的正确性证明:
❖最优子结构性质:假设最小生成树为T,从V-U集合中 添加到集合U中的结点顺序为< u0, …, ui, …, un-1, un>, 需要证明: 顺序< u0, …, ui, …, un-1>亦为图G’=(V\{un}, E\{e})最小生成树T’ ,其中e={原图G中与结点un相连 的边}。
贪心算法概述及研讨
对贪心算法的概述和研讨福州第一中学高一(8)班汪涛指导老师:陈颖算法总览当一个问题具有“最优子结构”时,我们可以采用动态规划法解决该问题。
但是有的时候,贪心算法可以更好的处理该类问题。
总体上看,贪心算法是一种高效的、不稳定的算法;但是它在解决问题时有很多独特的优良性质,掌握贪心算法有时可以非常迅速的获得最优解或近似最优解。
关键字:贪心算法(贪婪算法),贪心算法的应用举例,Object Pascal,快速算法,不稳定算法,信息学奥赛。
何时采用何时能,又何时应该采用贪心算法呢?一般认为,凡是经过数学归纳法证明可以采用贪心算法的情况,都应该采用它。
因为它的效率是很高的。
贪心算法的弱点在于它的不稳定性,即有时它不总能返回最优解。
那么能采用贪心算法的问题具有怎样的性质呢?(何时采用贪心算法)1、它具有和动态规划问题相似的性质,即分治法中的“最优子结构”性质,即每个子问题的最优解的集合就是整体最优解。
这是必须的性质,因为贪心算法解决的问题流程就需要依序研究每个子问题,然后综合之得出最后结果。
不能采用分治法解决的问题,是理论上是不能使用贪心算法的。
而且,必须拥有最优子结构性质,才能保证贪心算法返回最优解。
2、它必须具有一种特殊的“贪心选择性”。
这种性质类同于“最优子结构”性质,但又有一些小的差别。
我们知道,在动态规划中,每一个父问题结果的得出需要它的子问题作为条件;但是“贪心选择性”则不需要;贪心选择性所做的是一个非线性的子问题处理过程,即一个子问题并不依赖于另一个子问题,但是子问题间有严格的顺序性。
要证明一个问题具有“贪心选择性”,就必须证明每一步所做的贪心选择最终导致一个问题的整体最优解。
这也是必须的性质。
如果一个问题具有上述两个性质,理论上就应该采用贪心算法。
处理流程经由贪心算法处理的问题需要经过排序。
即把“最贪心”的子结果排在序列的最前面,一直到“最不贪心的”。
这是处理问题的第一步。
然后依序解决问题而得出最终结果。
贪心算法基本思想和典型例题(转)
贪⼼算法基本思想和典型例题(转)贪⼼算法⼀、算法思想贪⼼法的基本思路:——从问题的某⼀个初始解出发逐步逼近给定的⽬标,以尽可能快的地求得更好的解。
当达到某算法中的某⼀步不能再继续前进时,算法停⽌。
该算法存在问题:1. 不能保证求得的最后解是最佳的;2. 不能⽤来求最⼤或最⼩解问题;3. 只能求满⾜某些约束条件的可⾏解的范围。
实现该算法的过程:从问题的某⼀初始解出发;while 能朝给定总⽬标前进⼀步 do 求出可⾏解的⼀个解元素;由所有解元素组合成问题的⼀个可⾏解;⼆、例题分析1、[背包问题]有⼀个背包,背包容量是M=150。
有7个物品,物品可以分割成任意⼤⼩。
要求尽可能让装⼊背包中的物品总价值最⼤,但不能超过总容量。
物品 A B C D E F G重量 35 30 60 50 40 10 25价值 10 40 30 50 35 40 30分析:⽬标函数: ∑pi最⼤约束条件是装⼊的物品总重量不超过背包容量:∑wi<=M( M=150)(1)根据贪⼼的策略,每次挑选价值最⼤的物品装⼊背包,得到的结果是否最优?(2)每次挑选所占空间最⼩的物品装⼊是否能得到最优解?(3)每次选取单位容量价值最⼤的物品,成为解本题的策略。
实现这个算法是学习算法分析与设计这门课程的需要。
贪⼼算法是所接触到的第⼀类算法。
算法从局部的最优出发,简单⽽快捷。
对于⼀个问题的最优解只能⽤穷举法得到时,⽤贪⼼法是寻找问题次优解的较好算法。
贪⼼法是⼀种改进了的分级处理⽅法。
⽤贪⼼法设计算法的特点是⼀步⼀步地进⾏,根据某个优化测度(可能是⽬标函数,也可能不是⽬标函数),每⼀步上都要保证能获得局部最优解。
每⼀步只考虑⼀个数据,它的选取应满⾜局部优化条件。
若下⼀个数据与部分最优解连在⼀起不再是可⾏解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加为⽌。
这种能够得到某种度量意义下的最优解的分级处理⽅法称为贪⼼法。
选择能产⽣问题最优解的最优度量标准是使⽤贪⼼法的核⼼问题。
贪心算法总结
贪⼼算法总结简介贪⼼算法(英⽂:greedy algorithm),是⽤计算机来模拟⼀个“贪⼼”的⼈做出决策的过程。
这个⼈⼗分贪婪,每⼀步⾏动总是按某种指标选取最优的操作。
⽽且他⽬光短浅,总是只看眼前,并不考虑以后可能造成的影响。
可想⽽知,并不是所有的时候贪⼼法都能获得最优解,所以⼀般使⽤贪⼼法的时候,都要确保⾃⼰能证明其正确性。
本⽂主要介绍,在解决诸多贪⼼算法的问题之后的⼼得。
常⽤场景最常见的贪⼼算法分为两种。
「我们将 XXX 按照某某顺序排序,然后按某种顺序(例如从⼩到⼤)选择。
」。
「我们每次都取 XXX 中最⼤/⼩的东西,并更新 XXX。
」(有时「XXX 中最⼤/⼩的东西」可以优化,⽐如⽤优先队列维护)第⼀种是离线的,先处理后选择,第⼆种是在线的,边处理边选择。
常见的出题背景为:确定某种最优组合(硬币问题)区间问题(合理安排区间)字典序问题最值问题A最优组合硬币问题是贪⼼算法⾮常经典的题⽬,关于最优组合问题,我认为主要分为两种类型:简单 -- 直接排序之后按照某种策略选取即可复杂 -- 除了按照贪⼼策略外,还需要进⾏某些处理或者模拟硬币问题硬币问题有1元、5元、10元、50元、100元、500元的硬币各C1、C5、C10、C50、C100、C500枚。
现在要⽤这些硬币来⽀付A元,最少需要多少枚硬币?假设本题⾄少存在⼀种⽀付⽅法。
0≤C1、C5、C10、C50、C100、C500≤1090≤A≤109本题是上述说的简单类型的题⽬,简⽽⾔之要使得硬币最少,则优先使⽤⼤⾯额的硬币。
因此本题的解法便⾮常清晰了,只需要从后往前遍历⼀遍即可(默认为硬币已经按⾯额⼤⼩进⾏排序)const int V[6] = {1, 5, 10, 50, 100, 500};int A, C[6]; // inputvoid solve(){int ans(0);for (int i = 5; i >= 0; -- i){int t = min(A / V[i], C[i]);A -= t * V[i];ans += t;}cout << ans << '\n';}零花钱问题POJ3040 AllowanceDescriptionAs a reward for record milk production, Farmer John has decided to start paying Bessie the cow a small weekly allowance. FJ has a set of coins in N (1 <= N <= 20) different denominations, where each denomination of coin evenly divides the next-larger denomination (e.g., 1 cent coins, 5 cent coins, 10 cent coins, and 50 cent coins).Using the given set of coins, he would like topay Bessie at least some given amount of money C (1 <= C <= 100,000,000) every week.Please help him ompute the maximum number of weeks he can pay Bessie.Input* Line 1: Two space-separated integers: N and C* Lines 2..N+1: Each line corresponds to a denomination of coin and contains two integers: the value V (1 <= V <= 100,000,000) of the denomination, and the number of coins B (1 <= B <= 1,000,000) of this denomation in Farmer John's possession.Output* Line 1: A single integer that is the number of weeks Farmer John can pay Bessie at least C allowanceSample Input3 610 11 1005 120Sample Output111这题的题⽬⼤意是:农场主每天都要给贝西⾄少为C的津贴。
【精选】贪心算法
【精选】贪心算法贪心算法近年来的信息学竞赛中,经常需要求一个问题的可行解和最优解,这就是所谓的最优化问题。
贪心法是求解这类问题的一种常用算法。
在众多的算法中,贪心法可以算的上是最接近人们日常思维的一种算法,他在各级各类信息学竞赛、尤其在一些数据规模很大的问题求解中发挥着越来越重要的作用。
一、什么是贪心法贪心法是从问题的某一个初始状态出发,通过逐步构造最优解的方法向给定的目标前进,并期望通过这种方法产生出一个全局最优解的方法。
做出贪心决策的依据称为贪心准则(策略),但要注意决策一旦做出,就不可再更改。
贪心与递推不同的是,推进的每一步不是依据某一固定的递推式,而是做一个当时看似最佳的贪心选择,不断的将问题实例归纳为更小的相似子问题。
所以,在有些最优化问题中,采用贪心法求解不能保证一定得到最优解,这时我们可以选择其他解决最优化问题的算法,如动态规划等。
归纳、分析、选择贪心准则是正确解决贪心问题的关键。
二、贪心法的特点及其优缺点贪心法主要有以下两个特点:贪心选择性质:算法中每一步选择都是当前看似最佳的选择,这种选择依赖于已做出的选择,但不依赖于未作出的选择。
最优子结构性质:算法中每一次都取得了最优解(即局部最优解),要保证最后的结果最优,则必须满足全局最优解包含局部最优解。
利用贪心法解题的一般步骤是:1、产生问题的一个初始解;2、循环操作,当可以向给定的目标前进时,就根据局部最优策略,向目标前进一步;3、得到问题的最优解(或较优解)。
贪心法的优缺点主要表现在:优点:一个正确的贪心算法拥有很多优点,比如思维复杂度低、代码量小、运行效率高、空间复杂度低等,是信息学竞赛中的一个有力武器,受到广大同学们的青睐。
缺点:贪心法的缺点集中表现在他的“非完美性”。
通常我们很难找到一个简单可行并且保证正确的贪心思路,即使我们找到一个看上去很正确的贪心思路,也需要严格的正确性证明。
这往往给我们直接使用贪心算法带来了巨大的困难。
马丙鹏_计算机算法设计与分析_第四章_1
17
4.2 背包问题
1. 问题的描述
– 问题的形式描述 可行解: 满足上述约束条件的任一集合(x1,x2,…,xn) 都是 问题的一个可行解——可行解可能为多个。 (x1,x2,…,xn)称为问题的一个解向量。 最优解: 能够使目标函数取最大值的可行解是问题的最 优解——最优解也可能为多个。
20
20
4.2 背包问题
2. 贪心策略求解
– (1) 以目标函数作为度量标准 如:若ΔM=2,背包外还剩两件物品i,j,且有(pi= 4,wi=4) 和(pj=3,wj=2),则下一步应选择j而非i 放入背包:pi/2 = 2 < pj= 3 实例分析(例4.1) (p1,p2,p3) = (25,24,15), (w1,w2,w3) = (18,15,10) ∵ p1>p2> p3 ∴ 首先将物品1放入背包,此时x1=1,背包获得p1=25的效 益增量,同时背包容量减少w1=18个单位,剩余空间ΔM=2。 其次考虑物品2和3。就ΔM=2而言有,只能选择物品2或3 的一部分装入背包。
3. 贪心方法的一般策略
– 贪心方法
A(1) A(2) … A(n)
量度标准1
A1(1) … A1(n)
量度标准2
A2(1) … A2(n)
……
量度标准k
Ak(1) … Ak(n)
可行解1 次优解
可行解2 最优解
可行解k 次优解
12
12
4.1 一般方法
按照度量标准,从A中选择一个输 procedure GREEDY(A,n) 入,其值赋予x,并将之从A中删除 //A(1:n)包含n个输入// solution←Φ //将解向量solution初始化为空// for i←1 to n do 判断x是否可以包含在解向量中 x←SELECT(A) if FEASIBLE(solution, x) then solution←UNION(solution, x) endif repeat return (solution) 将x和当前的解向量合并成新 end GREEDY 的解向量,并修改目标函数
贪心算法
6.贪心方法模型
a.工程计划模型 b.部分背包与每步最优 c.构造贪心算法
a.工程计划模型
我们常常碰到这样的问题:完成一个工程需
要若干个步骤,每个步骤都有若干种方法, 图示—— 步骤a 步骤b 步骤c ... 步骤n 方法b1 方法c1 方法a1 方法b2 方法c2 方法n1 方法a2 方法b3 方法c3 方法c4
种树问题:一条街道分为n个区域(按1-n编号), 每个都可种一棵树。有m户居民,每户会要求在区 域i-j区间内种至少一棵树。现求一个能满足所有要 求且种树最少的方案。 算法构造: 1.对于要求,以区间右端(升序)为首要关键字, 左端(升序)为次要关键字排序。 2.按排好的序依次考察这些要求,若未满足,则在 其最右端的区域种树,这时可能会满足多个要求。 证明思路:解法并不唯一,关键是证明没有比该解 法更好的解法。按步骤1排序之后,会发现对于每 个要求,在最右边的区域内种树所得的结果总不会 差于在其他区域种树。至于为什么这样排序,留给 你——读者们思考吧。
每个方法有一个权值(如效率、质量),其大小往 往和其他步骤中选取的方法有关。有些时候权值无 意义,表示方法不可选择。要求给出一个方法组合, 是权值和最大。 在这里,暂且把它称作“工程计划”。很多实际问 题都可以归纳为这个模型。 对于不同形式的工程计划,我们有不同的解法。 若权值与整个过程或前后步骤的方法选择都有关, 我们使用搜索算法——时间复杂度高得吓人。 若每个权值只与上(或下)一步或少数几步的方法 选择都有关,我们使用动态规划——有比较高的效 率,在下一章会讲到。 若每个权值与其他步骤的方法选择都没有关系,我 们使用贪心方法。
算法分析:设a[i]为第I堆纸牌的张数(0<=I<=n), v为均分后每堆纸牌的张数,s为最小移动次数。 我们用贪心算法,按照从左到右的顺序移动纸牌。 如第I堆的纸牌数不等于平均值,则移动一次(即s 加1),分两种情况移动: 1.若a[i]>v,则将a[i]-v张从第I堆移动到第I+1堆; 2.若a[i]<v,则将v-a[i]张从第I+1堆移动到第I堆。 为了设计的方便,我们把这两种情况统一看作是将 a[i]-v从第I堆移动到第I+1堆,移动后有a[i]=v; a[I+1]=a[I+1]+a[i]-v. 在从第I+1堆取出纸牌补充第I堆的过程中可能回出 现第I+1堆的纸牌小于零的情况。
计算机算法设计与分析(王晓东第4版)第4章
23
最优解代价公式
c[i, j ]: Sij 最优解的大小 c[i, j ] = 0 if Sij = φ maxak ∈Sij {c[i, k ] + c[k, j ] + 1} if Sij = φ
School of Computer and Communication Engineer
24
活动选择问题动态规划方法
schoolcommunicationengineer一步一步构建问题的最优解决方案其中每一步只考虑眼前的最佳选择对解空间进行搜索时在局部范围内进行择优选取决定下一步搜索方向不是为了找到全部解而只是找出一种可行解在一定的情况下贪心算法找出的可行解将是最优解schoolcommunicationengineer42贪贪贪心心心算算算法法法基基基本本本要要要素素素算法包含一系列步骤每一步都有一组选择做出在当前看来最好的选择一个贪心算法是否产生最优解需要严格证明schoolcommunicationengineer最优子结构schoolcommunicationengineer贪贪贪心心心选选选择择择性性性质质质定定定义义义若若若一个优化问题的全局最优解可以通过局部最优选择得到则该问题称为具有贪贪贪心心心选选选择择择性性性
School of Computer and Communication Engineer 4
4.2 贪 心 算 法 基 本 要 素
• 算法包含一系列步骤, 每一步都有一组选择, 做出在 当前看来最好的选择 • 希望通过作出局部最优选择达到全局最优选择 • 一个贪心算法是否产生最优解, 需要严格证明
School of Computer and Communication Engineer
算法设计与分析论文(贪心算法)
贪心选择是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪 心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划 算法的主要区别。
贪心选择是采用从顶向下、以迭代的方法做出相继选择,每做一次贪心选择 就将所求问题简化为一个规模更小的子问题。对于一个具体问题,要确定它是否 具有贪心选择的性质,我们必须证明每一步所作的贪心选择最终能得到问题的最 优解。通常可以首先证明问题的一个整体最优解,是从贪心选择开始的,而且作 了贪心选择后,原问题简化为一个规模更小的类似子问题。然后,用数学归纳法 证明,通过每一步贪心选择,最终可得到问题的一个整体最优解。
物品超出背包容量为止。伪代码如下:
public static void DepWePr(double[][] a, double c, int[] ans) { // depend on
// the // weight // and price double[] w = new double[a[0].length]; // the weight of goods System.arraycopy(a[0], 0, w, 0, w.length); // copy the array
贪心算法
——不在贪心中爆发,就在贪心中灭亡 徐晓龙 武汉理工大学计算机科学与技术学院软件 ZY1101 班
摘要
本文介绍贪心算法的基本意义以及算法的使用范围,并通过具体的案例来分 析贪心算法的具体应用,从而指出其特点和存在问题。 关键字:贪心算法,贪心策略,TSP、0/1 背包
引言
我们用了 13 周的时间学完了《算法设计与分析》这本书。这本书中涵盖了 大量的常见算法,包括蛮力法、分治法、动态规划法、贪心算法等等。我最有印 象的就是贪心算法。贪心算法是一种有合理的数据组织和清晰高效的算法,它简 单有效。下面我们来详细解读一下这个算法。
贪心算法
max vi xi
i 1
n
于是,背包问题归结为寻找一个满足约束条 件式,并使目标函数式达到最大的解向量X=(x1, x2, …, xn)。
至少有三种看似合理的贪心策略: (1)选择价值最大的物品,因为这可以尽可能快 地增加背包的总价值。但是,虽然每一步选择获得 了背包价值的极大增长,但背包容量却可能消耗得 太快,使得装入背包的物品个数减少,从而不能保 证目标函数达到最大。 (2)选择重量最轻的物品,因为这可以装入尽可 能多的物品,从而增加背包的总价值。但是,虽然 每一步选择使背包的容量消耗得慢了,但背包的价 值却没能保证迅速增长,从而不能保证目标函数达 到最大。 (3)选择单位重量价值最大的物品,在背包价值 增长和背包容量消耗两者之间寻找平衡。
算法
main( ) { int i,j,n,GZ,A; int B[8]={0,100,50,20,10,5,2,1},S[8]; input(n); for(i=1;i<=n;i++) { input(GZ); for(j=1,j<=7;j++) { A=GZ/B[j]; S[j]=S[j]+A; GZ=GZ-A*B[j];} } for(i=1;i<=7;i++) print(B[i], “----”, S[i]); }
∞ b 4 0 a 8 h ∞ 4 b 4 0 a 8 h 8 11 7 11 7
8 ∞ i 6 1 2
∞ c
7
∞ d 14 9 e ∞ 10
4 g ∞
2
f ∞
(a)
8 ∞ i 6 1 g ∞ 2 4 f ∞ ∞ c 7 ∞ d 14 9 e ∞ 10 2
贪心法求解活动安排问题的关键是如何选择贪心策略,使 得按照一定的顺序选择相容活动,并能安排尽量多的活动。至 少有两种看似合理的贪心策略: (1)最早开始时间:这样可以增大资源的利用率。 (2)最早结束时间:这样可以使下一个活动尽早开始。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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相容。
30
4.2 贪心算法的基本要素
用贪心算法解背包问题的基本步骤:
首先计算每种物品单位重量的价值Vi/Wi,然 后,依贪心选择策略,将尽可能多的单位重量价值 最高的物品装入背ቤተ መጻሕፍቲ ባይዱ。若将这种物品全部装入背包 后,背包内的物品总重量未超过C,则选择单位重量 价值次高的物品并尽可能多地装入背包。依此策略 一直地进行下去,直到背包装满为止。 具体算法可描述如下页:
4.1 活动安排问题
例:设待安排的11个活动的开始时间和结束 时间按结束时间的非减序排列如下:
i
1 2
3 0 6
4 5 7
5 3 8
6 5
7 6
8 8
9 10 11 8 2 12
S[i] 1 3 f[i] 4 5
9 10 11 12 13 14
15
4.1 活动安排问题
算法greedySelector 的计算过程如左图所 示。图中每行相应于算 法的一次迭代。 阴影长条表示的活动 是已选入集合A的活动, 而空白长条表示的活动 是当前正在检查相容性 的活动。
17
4.1 活动安排问题
18
4.1 活动安排问题
19
4.1 活动安排问题
20
4.1 活动安排问题
首先证明最优解A的构成:前k步和剩 下活动的最优解;再根据剩下活动的 最优解和前k步一样,又包含剩下活动 的第一个的最优解,即第k+1个。
21
4.1 活动安排问题
思考:其它的贪心选择方案:
(1)选择具有最短时段的相容活动 (2)选择覆盖未选择活动最少的相 容活动 (1)(2)都无法获得最优解。 如右图所示活动系列: 最优解{1,2,3,4} (1)选择为{1,4,5} (2)的初选5,5一旦选中,最多只能再选两个
16
4.1 活动安排问题
若被检查的活动i的开始时间Si小于最近选 择的活动j的结束时间fi,则不选择活动i,否 则选择活动i加入集合A中。 贪心算法并不总能求得问题的整体最优 解。但对于活动安排问题,贪心算法 greedySelector却总能求得的整体最优解,即 它最终所确定的相容活动集合A的规模最大。 这个结论可以用数学归纳法证明。(书 P104-105)
【渴婴】 问题模型定义:设ai为第i种饮料的总量(假设以毫升 为单位),而婴儿需要t毫升的饮料来解渴,那么需 要饮用n种不同的饮料各多少才能满足婴儿解渴的需 求呢? 设各种饮料的满意度Si已知,令xi为将要饮用的第i种 饮料的量,那么需要解决的问题是:求解一组实数向 n 量xi(1≤i≤n),使得: S i xi 最大,并满足:
8
4.1 活动安排问题
活动安排问题就是要在所给的活动 集合中选出最大的相容活动子集合,是 可以用贪心算法有效求解的很好例子。 该问题要求高效地安排一系列争用某一 公共资源的活动。贪心算法提供了一个 简单、漂亮的方法使得尽可能多的活动 能兼容地使用公共资源。
9
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相容。
7
顾名思义,贪心算法总是作出在当前看来最 好的选择。 也就是说贪心算法并不从整体最优考虑, 它所作出的选择只是在某种意义上的局部最优 选择。 当然,希望贪心算法得到的最终结果也是 使用贪心法要解决的问题: 整体最优的。虽然贪心算法不能对所有问题都 得到整体最优解,但对许多问题它能产生整体 是否可以得到最优解? 最优解。如单源最短路经问题,最小生成树问 不能得到最优解,贪心解与最优解的 题等。在一些情况下,即使贪心算法不能得到 误差估计 整体最优解,其最终结果却是最优解的很好近 似。
27
对具体的一个问题,能否用贪心法得到最优 解。
动态规划法实质: 贪心法实质: 当前状态下的最 好选择。
自底向上
自顶向下
求相关子问题后, 做出选择。
28
4.2 贪心算法的基本要素
0-1背包问题:
给定n种物品和一个背包。物品i的重量是Wi, 其价值为Vi,背包的容量为C。应如何选择装入背 包的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i只有 2种选择,即装入背包或不装入背包。不能将物品 i装入背包多次,也不能只装入部分的物品i。
31
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]; }
4.2 贪心算法的基本要素
2、最优子结构性质
当一个问题的最优解包含其子问题的最优 解时,称此问题具有最优子结构性质。问题的 最优子结构性质是该问题可用动态规划算法或 贪心算法求解的关键特征。
26
4.2 贪心算法的基本要素
3、贪心算法与动态规划算法的差异
贪心算法和动态规划算法都要求问题具有最优 子结构性质,这是2类算法的一个共同点。但是, 对于具有最优子结构的问题应该选用贪心算法还是 动态规划算法求解?是否能用动态规划算法求解的 问题也能用贪心算法求解?下面研究2个经典的组合 优化问题,并以此说明贪心算法与动态规划算法的 主要差别。
第4章 贪心算法
1
学习要点
贪心算法的基本思想 贪心算法的基本要素
(1)最优子结构性质 (2)贪心选择性质
贪心算法与动态规划算法的差异 正确性的证明 范例学习贪心设计策略
(1)活动安排问题; (4)单源最短路径; (2)最优装载问题; (5)最小生成树; (3)哈夫曼编码; (6)多机调度问题。
29
4.2 贪心算法的基本要素
背包问题:
与0-1背包问题类似,所不同的是在选择物品i 装入背包时,可以选择物品i的一部分,而不 一定要全部装入背包,1≤i≤n。 这2类问题都具有最优子结构性质,看似相 似,但却是两种不同难易度的问题。 背包问题可以用贪心算法求解,而0-1背包问 题却不能用贪心算法求解。
2
难!
【渴婴】 有一个非常渴的、但很聪明的小婴儿。她可能得到的东 西包括:一杯水、一小罐牛奶、多罐其它不同种类的 果汁……。即婴儿可能得到n种不同口味的饮料。 根据以前对这n种饮料的不同体验,这个婴儿知道其中 某种饮料更适合自己的胃口,因此婴儿采用如下方法 为每一种饮料赋予一个满意度值,即Si作为满意度赋 予第i种饮料。 通常,这个婴儿都会尽量饮用具有最大满意度的饮料来 最大限度地满足她解渴地需要,但不幸地是:她最满 意地饮料有时并没有足够地量来满足这个婴儿解渴地 需要。 3
5
贪心算法 形象模型
最高峰 次高峰 小山峰 小山峰 小山峰 小山峰
6
顾名思义,贪心算法总是作出在当前看来最 好的选择。 也就是说贪心算法并不从整体最优考虑, 它所作出的选择只是在某种意义上的局部最优 选择。 当然,希望贪心算法得到的最终结果也是 整体最优的。虽然贪心算法不能对所有问题都 得到整体最优解,但对许多问题它能产生整体 最优解。如单源最短路经问题,最小生成树问 题等。在一些情况下,即使贪心算法不能得到 整体最优解,其最终结果却是最优解的很好近 似。
24
4.2 贪心算法的基本要素
1、贪心选择性质
所谓贪心选择性质是指所求问题的整体最优解可以 通过一系列局部最优的选择,即贪心选择来达到。这是 贪心算法可行的第一个基本要素,也是贪心算法与动态 规划算法的主要区别。 动态规划算法通常以自底向上的方式解各子问题,而 贪心算法则通常以自顶向下的方式进行,以迭代的方式 作出相继的贪心选择,每作一次贪心选择就将所求问题 简化为规模更小的子问题。 对于一个具体问题,要确定它是否具有贪心选择性 质,必须证明每一步所作的贪心选择最终导致问题的整 25 体最优解。
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美 分,且希望用最少数目的钱币找给小孩。 解:售货员每次加入一种钱币,并采用的贪婪准则 是:每次选择的某种钱币面值尽可能大,所需张数 尽可能少,但同时需保证解法的可行性(即,所给 的零钱等于要找的零钱数,不多给不少给)。
11
4.1 活动安排问题