第四章贪心算法
第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++;
计算机算法设计与分析--第4章 贪心算法幻灯片PPT

本PPT课件仅供大家学习使用 请学习完及时删除处理 谢谢!
提纲
一、贪心算法的基本思想 二、活动安排问题 三、最优装载 四、哈夫曼编码 五、单源最短路径 六、最小生成树 七、多机调度问题
2021/5/19
2
提纲
一、贪心算法的基本思想 二、活动安排问题 三、最优装载 四、哈夫曼编码 五、单源最短路径 六、最小生成树 七、多机调度问题
一、贪心算法的基本思想 二、活动安排问题 三、最优装载 四、哈夫曼编码 五、单源最短路径 六、最小生成树 七、多机调度问题
2021/5/19
28
3.1 问题定义
Optimal Loading problem
有一批集装箱要装上一艘载重量为c的轮船。其 中集装箱i的重量为Wi。最优装载问题要求确定 在装载体积不受限制的情况下,将尽可能多的 集装箱装上轮船。
2021/5/19
21
2.3贪心算法
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++) {
各活动的起始时间和结 束时间存储于数组s和f 中且按结束时间的非减
2.4 算法正确性证明
需要证明:
活动安排问题有一个最优解以贪心选择开始; 活动安排问题具有最优子结构; 算法每一步按照贪心选择计算,最终可得到
原问题的一个最优解。
2021/5/19
24
2.4 算法正确性证明
定理1 设E={1,2,…,n}是n个活动集合,[si,fi ]是活动 的起始终止时间,且f1f2….fn,E的活动安排 问题的某个最优解包括活动1.
第4章 贪心算法(1)活动安排问题

4.1 活动安排问题
活动安排问题是可以用贪心算法有效求解的很 好例子。
该问题要求高效地安排一系列争用某一公共资 源的活动,使得尽可能多的活动能兼容地使用 公共资源。
4
问题描述
设有n个活动的集合E={1, 2, …, n},其中每个 活动都要求使用同一资源,而在同一时间内只 有一个活动能使用这一资源。
2
贪心算法
例2:若上述硬币面值改为:
一角一分、五分和一分 现在要找给顾客一角五分钱,如何给出硬币? 答案:错:1个一角一分,4个一分
对:3个五分
虽然贪心算法不能对所有问题都得到整体最优 解,但对许多问题它能产生整体最优解。
在一些情况下,即使贪心算法不能得到整体最 优解,其最终结果却是最优解的很好的近似解。
ቤተ መጻሕፍቲ ባይዱ17
0-1背包问题
给定n种物品和一个背包。物品i的重量是wi, 其价值为vi,背包的容量为c。应如何选择装 入背包的物品,使得装入背包中物品的总价 值最大?
说明:在选择装入背包的物品时,对每种物 品i只有2种选择,即装入背包或不装入背包。 不能将物品i装入背包多次,也不能只装入部 分的物品i。
16
3、贪心算法与动态规划算法的 差异
贪心算法和动态规划算法都要求问题具有最 优子结构性质,这是两类算法的一个共同点。
对于具有最优子结构的问题应该选用贪心算 法还是动态规划算法求解?
是否能用动态规划算法求解的问题也能用贪 心算法求解?
下面研究2个经典的组合优化问题,并以此 说明贪心算法与动态规划算法的主要差别。
每个活动i都有一个要求使用该资源的起始时 间si和一个结束时间fi,且si <fi 。
5
问题描述
如果选择了活动i,则它在半开时间区间[si, fi) 内占用资源。若区间[si, fi)与区间[sj, fj)不相交, 则称活动i与活动j是相容的。也就是说,当si≥fj
贪心算法讲义

float p[1..n], w[1..n], x[1..n], M, rc;
integer i, n; x:= 0; // 将解向量初始化为零
//w[1..n],它们元素的排列 //顺序满p[i]/w[i]≥p[i+1]/w[i+1] //M是背包容量,x[1..n]是解向量
rc:= M; // 背包的剩余容量初始化为M
作业调度问题
单机作业调度问题的贪心算法
将上述算法找到的作业集按作业期限升序排列,就产生一 个作业调度。
算法的复杂度分析
J {i}的相容性判断最坏|J|次,|J|最大i-1。所以 T(n)=1+2+…+n-1=O(n2)
例子: 设n=7,
(p1, p2,… ,pn)=(35,30,25,20,15,10,5), (d1, d2,… ,dn)=(4,2,4,3,4,8,3) 算法GreedyJob的执行过程 : 作业 1 ;2, 1; 2, 1, 3; 2, 4, 1, 3; 2, 4, 1, 3 , 6; 期限 4; 2, 4; 2,4, 4; 2, 3, 4, 4; 2, 3, 4, 4, 8;
带期限的单机作业安排问题
已知n项作业 E={1, 2, … ,n}要求使用同台机器完成, 而且每项作业需要的时间都是1。第k项作业要求在时 刻2, d…k之, n前。完成, 而且完成这项作业将获得效益pk,k=1,
作业集E的子集称为相容的如果其中的作业可以被安 排由一台机器完成。
带限期单机作业安排问题就是要在所给的作业集合中 选出总效益值最大的相容子集。
许多NP难组合优化问题,目前仍未找到有效的算法, 贪心策略常用于设计这些问题的近似算法。
贪心算法的基本思想
第4章贪心算法

使得这N支商队在这次经商中获得的总收益最大
注意:你的每支商队只能进行一次交易
即它们只能从它们所在的城市到达一个相邻的城市
当然
它们也可以不进行任何交易
4
2 1 4 3
输出:
13
【算法分析】
当看到此题时
我们会发现求max与求min是两个相似的过程
若我们把求解max与min的过程分开
着重探讨求max的问题
下面我们以求max为例来讨论此题用贪心策略求解的合理性
讨论:假设经(N-3)次变换后得到3个数:a ,b , max'(max'≥a≥b)
}
int work(){
qsort(a+1,n,sizeof(a[0]),cmp);//按区间右端点由小到大排序
int i,j,k;
int a1,a2;
a1=a[1].right-1;a2=a[1].right;result=2;
for(i=2;i<=n;i++)
{ if(a[i].left<=a1&& a[i].right>=a2)continue;//完全包含
struct prince{
int left,right;//区间左右端点
}a[10000];
int n;
int result;//存放结果中的数
int cmp(const void *a,const void *b){
return (*(prince *)a).right-(*(prince *)b).right;
}
return result;
(算法分析与设计)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;
第4章 贪心算法

4.1 活动安排问题
若被检查的活动i的开始时间Si小于最近选择的活动j 的结束时间fi,则不选择活动i,否则选择活动i加入集 合A中。
贪心算法并不总能求得问题的整体最优解。但对 于活动安排问题,贪心算法greedySelector却总能求 得的整体最优解,即它最终所确定的相容活动集合A的 规模最大。这个结论可以用数学归纳法证明。
if (s[i]>=f[j]) { A[i]=true; j=i; }
各活动的起始时间和结 束时间存储于数组s和f 中且按结束时间的非减
序排列
else A[i]=false;
}
}
6
4.1 活动安排问题
由于输入的活动以其完成时间的非减序排列, 所以算法greedySelector每次总是选择具有最早 完成时间的相容活动加入集合A中。直观上,按这 种方法选择相容活动为未安排活动留下尽可能多 的时间。也就是说,该算法的贪心选择的意义是 使剩余的可安排时间段极大化,以便安排尽可能 多的相容活动。
1、算法基本思想
Dijkstra算法是解单源最短路径问题的贪心算法。
28
4.5 单源最短路径
其基本思想是,设置顶点集合S并不断地作贪心选 择来扩充这个集合。一个顶点属于集合S当且仅当从源 到该顶点的最短路径长度已知。
初始时,S中仅含有源。设u是G的某一个顶点, 把从源到u且中间只经过S中顶点的路称为从源到u的 特殊路径,并用数组dist记录当前每个顶点所对应的最 短特殊路径长度。Dijkstra算法每次从V-S中取出具有 最短特殊路长度的顶点u,将u添加到S中,同时对数 组dist作必要的修改。一旦S包含了所有V中顶点,dist 就记录了从源到所有其它顶点之间的最短路径长度。
要证明哈夫曼算法的正确性,只要证明最优前缀 码问题具有贪心选择性质和最优子结构性质。
《计算机算法设计与分析》PPT第四章贪心算法资料

假设活动已按结束时间的单调非递减顺序排序 f0≤f1≤f2≤… ≤fn<fn+1
则,当i≥j时, Sij=φ。
假设存在一活动ak∈Sij,其中i≥j,则在已排的序列中 ai在aj后面。
因fi≤sk<fk≤sj<fj ,与在已排的序列中ai在aj后面的 假设相矛盾。
所以,设活动按结束时间的单调非递减顺序排序,子 问题空间被用来从sij中选择最大相容活动子集,其中 0≤i<j≤n+1,而且所有其它的sij是空的。
14
步骤2:递归地定义最优解的值 设c[i, j]为Sij中最大相容子集中的活动数。当 Sij=φ时,c[i, j] = 0。对于一个非空子集Sij, 如果ak在Sij的最大相容子集中被使用,则子问 题Sik和Skj的最大相容子集也被使用。从而:
c[i, j] = c[i, k] + c[k, j] + 1
活动安排问题:要在所给的活动集合中选出最大 的相容活动子集合。
10
用动态规划方法求解
步骤1:分析最优解的结构特征 构造子问题空间 Sij={ ak∈S: fi≤sk<fk≤sj} Sij是S中活动的子集,其中每个活动都在活动ai 结束之后开始,且在活动aj开始之前结束。 Sij包含了所有与ai和aj相容的活动,并且与不迟 于ai结束和不早于aj开始的活动相容。此外, 虚构活动a0和an+1,其中f0=0, Sn+1=∞。原 问题即为寻找S0,n+1中最大相容活动子集。
(5)约束函数constraint:检查解集合中加入一 个候选对象是否满足约束条件。例如,在找零钱 问题中,约束函数是每一步选择的货币和已付出 的货币相加不超过应找零钱。
7
贪心算法的一般框架
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第四章贪心算法
一、课本+作业
DIJKSTRA的主要思想
算法的思想是把中心定在起始顶点,向外层结点扩展,最终在目标顶点结束,停止扩展。
设顶点集合为S,通过贪心选择,逐步扩充这个集合。
一开始,集合S中所包含顶点仅为源点。
设u为图G的某一结点,把从开始顶点到结点u,且中间经过的顶点均在集合S内的线路称为从源点到u的特殊路径。
创建一个数组SD,用于储存每个顶点所对应的最短特殊路径的长度。
算法每次从u∈V-S 中取出具有最短特殊路长度的顶点u,将u添加到集合S中,与此同时,修改数组SD。
当S包含了所有V中顶点时,SD就记录了从源到所有其它顶点之间的最短路径长度。
Dijkstra算法的时间复杂度为O(n2),空间复杂度随着选择的存储方式不同而有所变化,若存储方式为邻接矩阵时为O(n2)。
在求解单源最短路径问题时,Dijkstra算法可以得到最优解,但由于它需要遍历众多结点,所以效率低。
历年试题
1.(2011年)试用Prim算法求解下面无向赋权图的最小生成树,指出最小生成树及该树中各边被选中的先后次序;写出算法的基本步骤。
2. (2010)1.分析Kruskal 算法的时间复杂度;
2. 试用下面的例子说明用Kruskal 算法求解最优生成树问题,并总结出算法的
基本步骤:
3.(2009)(原理习题有)
4. (2006) 设n p p p ,,,21 是准备存放到长为L 的磁带上的n 个程序,程序i p 需要的带
长为i a 。
设L a n
i i >∑=1,要求选取一个能放在带上的程序的最大子集合(即其中含有
最多个数的程序)Q 。
构造Q 的一种贪心策略是按i a 的非降次序将程序计入集合。
1). 证明这一策略总能找到最大子集Q ,使得∑∈≤Q
p i i L a 。
2). 设Q是使用上述贪心算法得到的子集合,磁带的利用率∑
∈Q
p i
i
L
a/可以小到何种程
度?
3). 试说明1)中提到的设计策略不一定得到使∑
∈Q
p i
i
L
a/取最大值的子集合(习题)
4.( 2009)。