02-算法设计与分析-贪心算法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Chapter 2 GREEDY ALGORITHMS
(4)还有一个函数,检查候选对象是否可加入到当 前解的对象集合中,不一定是最优的。 (5)选择函数(selection function),指出哪个 剩余的候选对象最有可能构成问题的解。
(6)目标函数(object function),给出解的值。如 硬币个数,路径长度,顶点个数等。
Chapter 2 GREEDY ALGORITHMS
回到找钱问题上来,看看其一般特性:
源自文库
(1)找最少硬币数,候选对象集 {100,25,10,5,1}
(2)一选到的硬币集和未被选的硬币集。
(3)判断解函数(solution),检查目前已选的硬币 集中的金额是否等于要找的钱数。
(4)如果集合中硬币签署不超过应找金额,则该集 合是可行的。 (5)选择函数(selection),从未选硬币集合中找 一个面值最大的硬币。 (6)目标函数(object):计算硬币数目。
Chapter 2 GREEDY ALGORITHMS
Kruskal算法的实现: 采用FMS(Find Merge Set) Function Kruskal(G=<N,A>:graph,length:A>R+):set of egdes Sort A bay increasing length n=|N| T=Φ {T是最小生成树的边集} 初始化n个集合(树),每个顶点是一个集合 repeat e=(u,v) A-T中的最小边 a=find(u) b=find(v) if a<>b then merge(a,b)
Chapter 2 GREEDY ALGORITHMS
2.3.2 Prim算法 算法思想: G=(V,E) (1)T为空, B为任意顶点 (2)从B和V-B之间的边中选一最小边(u,v), u属于B,v 属于V-B。 (3)将(u,v)加入T,将v加入B (4)重复(2)-(3)n-1次 是一个贪婪算法。
10
1 7 5
2
14
18 16
6
24
7
25
18
3
12
6
24
3
12
5
22 4
22 4
edge
1 2 3 4 5 6 7 8 9
u 1 3 2 2 4 4 5 5 1
v 6 4 7 3 7 5 6 7 2
w 10 12 14 16 18 22 24 25 28
Chapter 2 GREEDY ALGORITHMS
2.3.1 Kruskal算法 Kruscal 算法 算法思想: (1)将所有边按权由小到大排列 ; (2)MST置空; (3)依次取最小边(u,v): * 若(u,v)加入MST不构成回路则将(u,v)加入 MST; * 若MST中的边达到n-1条,则结束;
Kruscal算法的例:
10
1
28
2
14 16
Chapter 2 GREEDY ALGORITHMS
定理 2.1 图中无负边,从1个源点开始,Dijkstra 算法可以找到图中其他所有顶点的最短路径。 证明:数学归纳证明: (a)如果一个顶点i满足i<>1,且i在S中,则D[i]给出 了从源到i的最短路径长度。 (b)一个顶点i不在S中,则D[i]给出了从源到i的最短 特殊路径长度。(i的前驱在S中)
Chapter 2 GREEDY ALGORITHMS
2.3 图:最小生成树
最小生成树的算法有2个,prim算法和Kruskal算法。 他们都是贪婪算法。但得到解是最有的。 该问题的一般特性: (1)最小生成树,是最小优化。候选对象是图的边 集。 (2)已选中的边集MST,未选边集E-MST
(3)solution:如果MST构成生成树,则它是一个解。
一个候选解可以扩充为问题的解,也可以扩充为问题 的最优解。
Chapter 2 GREEDY ALGORITHMS
MST的重要性质: 引理 6.3.1: 设N=(V, E, W) 是连通网,V是顶点集, E是边集, W={wij | (vi,vj)的权 }
U是V的非空真子集。 若(u,v)是边权最小的边,其中 u属于U, v属于V-U, 则必有一个MST包含(u,v)。 证明:反证法。 设N的任何MST都不包含(u,v)。设T是N的一个MST, 将(u,v)加入T,形成回路,如图所示。
Chapter 2 GREEDY ALGORITHMS
只要有足够多的硬币,算法总能找到最优解,如 果某些种类的硬币数量不足时,可能得不到最优解。
2.2 贪婪算法的一般特性
一般,贪婪算法可解的问题有如下特性: (1)优化问题,有一个候选对象的集合,如硬币, 边,路径,顶点等。
(2)随着算法的进行,形成2个集合,一个是已经被 选中的对象集合,另一个是被抛弃的对象集合 (3)有一个函数(solution),检查候选对象集是 否是问题的解,不一定是最优的。
Chapter 2 GREEDY ALGORITHMS
第 2章
贪心算法
贪心算法是一大类算法,解决问题的策略是只考 虑眼前情况。因此算法容易设计和实现。也比较高效, 但有时得不到正确的解。 贪心算法的典型应用是解决组合优化问题。
2.1
找零钱(1 Making change )
发行硬币有 1元(100分),2角5分(25分),1角, 5分,1分。 设计一个算法,用最少的硬币数找钱。
10 1 2
0 30
100 4 60 3
50 10
20
Chapter 2 GREEDY ALGORITHMS
边上有负权值的情况 带权有向图D的某几条边或所有边的长度可能为负值。 利用Dijkstra算法,不一定能得到正确的结果。 5
0 7 1 -5
2
源点0到终点2的最短路径应是0, 1, 2,其长度为2, 它小于算法中计算出来的dist[2]的值。
U u
V-U v
(u,u’)连通, (v,v’)连通,
去掉(u’,v’)得到自由 树 T’ , 因 wuv<wu’v’,所以T’ 的边权之和小于T 的边权之 和,与T是MST矛盾。
u’
v’
Prim算法和Kruskal算法都是利用MST的性质构造MST 的。 下面先介绍 Prim算法。
Chapter 2 GREEDY ALGORITHMS
Chapter 2 GREEDY ALGORITHMS
function
greedy(C:set):set
{C是候选对象集合}
S=Φ {在集合S中构造解}
while C<>Φ and not solution(S) do
x=select(C)
C=C\{x}
if feasible(S∪{x}) then S=S∪{x} if solution(S) then return S else return “No solution”
归纳基础:初始S 中只有源点1,所以(a)明显成立。 对于不属于S 的顶点i,D[i]是L[1,i],(b)也成立。 归纳假设:假设在往S添加v之前,条件(a)(b)都成立。 条件(a)的归纳: 将v加入S,即 D[v]最小。
Chapter 2 GREEDY ALGORITHMS
条件(a)的归纳: 将v加入S,即 D[v]最小。且所经 过的顶点都在S中。 否则,假设至少经过了x, D[v]<D[x], x
(4)候选边加入MST构不成回路,则该边可以加入 MST
Chapter 2 GREEDY ALGORITHMS
(5)selection: 根据算法而定,如prim算法中,选 择U和V-U之间的最小边。 KrusKal算法是从未选边中 选最小边。 (6)目标函数(object):计算MST中边权值和。
Chapter 2 GREEDY ALGORITHMS
T=T∪{e} until T contains n-1 egdes return T
算法分析:a=|A| • A排序开销 Θ(aloga) • 初始化n个集合开销 Θ(n) • 所有的find和merge开销是Θ(2aα(2a,n)),实际 上只需要2a次find和n-1次merge • 对于剩余的操作,最坏情况是O(a)
用普里姆算法构造最小生成树的过程
1
5 7 5 6 8 12 4 3 11
4
6
8 10 3
2
Chapter 2 GREEDY ALGORITHMS
定理6.3.3 Prim算法可以找到一个最小生成树。 证明:归纳于T中边的数目,如果T在任何步骤都是有 希望的,则往T里加一条边后,仍然是有希望的。 归纳基础:空集合是有希望的。 归纳假设:T中的边数<s时是有希望的。 归纳步骤:当往T里加一条边新的边e=(u,e),u属于 B,v属于V-B,且是B和V-B之间最小的边,有MST的 性质知道,T仍然是有希望的。 因在算法每一步T都是有希望的,所以算法结束后, T是最小生成树。
Dijkstra算法中各辅助数组的变化
选取 顶点 1 顶点 2 终点 S[1] d[1] p[1] S[2] d[2] p[2]
0 1 3 2 4 0 1 1 1 1 10 10 10 10 10 0 0 0 0 0 0 0 0 1 1 60 50 50 50 0 1 3 3 3
顶点 3
S[3] 0 0 1 1 1 30 30 30 30 30 0 0 0 0 0 0 0 0 0 1
Chapter 2 GREEDY ALGORITHMS
2.4 图:最短路径 单源最短路径问题。 用Dijkstra算法。 Function Dijkstra(L[1..n,1..n]):array[2..n] array D[2..n] C={2,3,…,n} for i=2 to n do D[i]=L[1,i] for i=2 to n do v=some element of C minimizing D[v] C=C\{v} for each w∈C do D[w]=min{D[w],D[v]+L[v,w]} return D
Chapter 2 GREEDY ALGORITHMS
人们一般都采取贪心算法找钱,就是:每一步都 选出最大值的币。 算法: Function change(m) const c={100,25,10,5,1} S=Φ; s=0 while s<>n do x=(max in C and s+x<=n) if there is no such item then retun “no solution found” S=S∪{a coin of x} s=s+x return S
FUNDAMENTALS OF ALGORITHMICS Giles Brassard Paull Bratley Chapter 2
GREEDY ALGORITHMS
CS Inner Mongolia U Prof. WANG Junyi
2.1 找零钱
2.2 贪婪算法的一般特性
2.3 图:最小生成树 2.4 图:最短路径 2.5 背包问题 2.6 日程安排
v 条件(b)的归纳: 将v加入后,对任何一个不属于S的 w, w 算法分析:O(n2)
v
Chapter 2 GREEDY ALGORITHMS
2.5 背包问题 该问题有多个版本,现给出最简单的一个。 有n个物品1,2,3,4,…,n,重量分别是 w1,w2,….,wn ,价值分别是v1,v2,…,vn,一个背包 可装重量为W。目标是,使装入物品的总价值最大。 第一版本: 物品可以分割,可将物品i的xi(0<=xi<=1)部分装 入背包,其重量是xiwi,价值是xivi, 问题形式化 描述为:
Kruskal算法正确性证明: 证明:施归纳与G的边数 归纳基础:当G只有一条边,显然G就是最小生成树; 归纳假设:设T中有s<n-1条边时,T是有希望成为最 有解的。 当 往T中再加一条最小边(u,v)时,且进入后不会 使T构成回路。原T中有若干联通分量,加入(u,v) 后,减少一个。所以加入后T仍然是有希望成为最 有解的。 所以算法结束后,T中有n-1条边,构成了生产树。且 是最优的。
顶点 4
p[4] 0 0 3 2 2 100 100 90 60 60
d[3] p[3] S[4] d[4]
如何从表中读取源点0到终点v的最 短路径?举顶点4为例 path[4] = 2 →path[2] = 3 → path[3] = 0,反过来排列,得到路 径0, 3, 2, 4,这就是源点0到终点4的 最短路径。
相关文档
最新文档