Chapter13-贪婪算法
贪婪算法是一种什么方法
贪婪算法是一种什么方法贪婪算法(Greedy Algorithm)是一种简单而经典的算法设计方法,通常用于解决优化问题。
贪婪算法每一步都采取当前情况下最优的选择,希望最终得到全局最优解。
本文将介绍贪婪算法的基本原理、应用场景以及一些经典的贪婪算法实例。
基本原理贪婪算法的基本原理是通过局部最优解来推导得到全局最优解。
在每一步中,贪婪算法选择当前看起来最好的选择,而不考虑之后的结果能否达到最优。
这种直观的选择策略有时可以给出全局最优解,但并非在所有问题中都成立。
贪婪算法的设计过程通常包含以下几个步骤:1. 定义问题的解空间和解集合,将问题转化成对这些解的选择和判定。
2. 根据问题的特点,设计选择策略,确定选择的标准。
3. 使用选择策略,逐步构建解,直到满足问题要求或无法继续选择。
需要注意的是,贪婪算法只能提供近似解,不能保证一定能得到最优解。
因此,在应用贪婪算法时需要仔细分析问题的性质,确定贪婪选择的合理性。
应用场景贪婪算法通常应用于具有贪婪选择性质的问题,即每一步都可以做出局部最优选择的问题。
这种性质常见于以下场景:最小生成树在图论中,最小生成树问题是指在一个连通无向图中找到一棵包含所有顶点且边权重之和最小的树。
典型的贪婪算法解决该问题的方法是普利姆算法(Prim's Algorithm)和克鲁斯卡尔算法(Kruskal's Algorithm)。
普利姆算法从一个起始顶点出发,每次选择与当前生成树连接的最短边对应的顶点,直到生成树包含所有顶点。
而克鲁斯卡尔算法则是从边集合中每次选择最小的边,同时保证不形成环,直到生成树包含所有顶点。
背包问题背包问题是在给定背包容量和一系列物品的重量和价值的情况下,如何选择物品放入背包中,使得背包中物品的总价值最大。
贪婪算法在背包问题的解决中有时也能给出较好的近似解。
一种典型的贪婪算法解决背包问题的方法是基于每个物品的单位价值(即单位重量所能获得的价值)来进行选择。
13-贪婪算法-1-47页PPT文档资料
2019/9/26
10
算法的基本思路
LOGO
从问题的某一个初始解出发逐步逼近给定的 目标,以尽可能快的地求得更好的解。当达 到某算法中的某一步不能再继续前进时,算 法停止。
存在问题:
1.不能保证求得的最后解是最佳的;
2.不能用来求最大或最小解问题;
3.只能求满足某些约束条件的可行解的范围。
然后,按照贪婪准则“先旧后新”将任务分配给机 器
2019/9/26
13
LOGO
求解: 设各种饮料的满意度已知。令Xi为婴儿将要引用的第
i种饮料的量,需要解决的问题是:找到一组实数 Xi(1<=i<=n)使满足
n
限制条件: xi t及0xi ai
i1
优化函数:
注意:可行解、优化解、无解的情况
2019/9/26
14
例13-2 装载问题
13.1 示例问题提出 13.2 贪婪算法的思想 13.3 贪婪算法的应用
货箱装船 拓扑排序 单源最短路径 最小耗费生成树
2019/9/26
LOGO
9
LOGO
贪婪算法是指:在对问题求解时,总是做出在当 前看来是最好的选择。也就是说,不从整体最优上加 以考虑,他所做出的仅是在某种意义上的局部最优解。
LOGO
2019/9/26
15
LOGO
装载问题 求解:找到一组变量Xi,其可能取值为0或1,
使它满足 限制条件:
优化函数:
n
xi
i1
2019/9/26
16
例13-3 最小代价通讯网络
LOGO
2019/9/26
最小耗费生成树
17
LOGO
贪心算法贪婪算法
编码结果:
a:00 b:110 c:10 d:111 e:01 共需:
2 20+3 7+2 10 +3 4+2 18=129bit
59 x4
1
0
38 x3
0
1
20
18
a
e
21 x2
1
0 11 x1
0
1
10
7
4
c
b
d
14
多机调度问题
多机调度问题要求给出一种作业调度方案,使所给 的n个作业在尽可能短的时间内由m台机器加工处理完
26 26 , 27 27 , 28 28, 29 29 , 210 2210 , 211 211, 212 212
时的运行时间与MATLAB自带的矩阵相乘的运
行时间,绘制时间对比图。
18
成。 约定,每个作业均可在任何一台机器上加 工处理,但未完工前不允许中断处理。作业 不能拆分成更小的子作业。
这个问题是NP完全问题,到目前为止还没有有效的解法。 对于这一类问题,用贪心选择策略有时可以设计出较好 的近似算法。
15
多机调度问题
采用最长处理时间作业优先的贪心选择策略可以设 计出解多机调度问题的较好的近似算法。
在选择装入背包的物品时,对每种物品i只有2种选择,即装入背 包或不装入背包。不能将物品i装入背包多次,也不能只装入部 分的物品i。
4
❖ 背包问题:
与0-1背包问题类似,所不同的是在选择物品i装入背包时, 可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n。
这2类问题极为相似,但背包问题可以用贪心算法求 解,而0-1背包问题却不能用贪心算法求解。
6
13章贪心算法-2015
贪心算法描述
在下面所给出的解活动安排问题的贪心算法greedySelector :
public static int greedySelector(int [] s, int [] f, boolean a[]) { int n=s.length-1; a[1]=true; int j=1; 各活动的起始时间和 int count=1; 结束时间存储于数组s for (int i=2;i<=n;i++) { 和f中且按结束时间的 if (s[i]>=f[j]) { 非减序排列 a[i]=true; j=i; count++; } else a[i]=false; } return count; }
i 1
n i i
n
c
p x ,等于装入物品的总效益值 目标函数: 极大化目标函数
i 1
0/1背包问题
0/1背包问题有多种贪心策略
(1)从未装入的物品中,选出效益值最大的物品装 入.利用这种规则,效益值最大的物品首先被装 入(假设有足够容量),然后是下一个效益值最大 的物品,如此进行下去. 注:这种策略不一定能保证得到最优解 n=3,c=105,w=[100,10,10],p=[20,15,15]
例:最短路算法
给定一个有向图G, 一个源节点s,目的节点d; 找从s 到 d 的一条最短路径.
从s开始选离s“最近”的下一个节点q; 再从q开始找 和q相邻的且不在前面已选择的路径上的下一节点;
重复这一过程直到遇到d节点或该路径无法继续延伸. 贪心解不是优化解: 按贪心法找到的1到5的路径为(1, 3, 4, 2, 5).
《贪心算法》PPT课件
{x1,x2,x3} {1,2/15,0} { 0,2/3,1} {0,1,1/2} {...}
n
wixi
20
i1
n
vixi
i1
20
20
...
31
...
[算法思路]1).将各物体按单位价值由高到低排序. 2).取价值最高者放入背包. 3).计算背包剩余空间. 4).在剩余物体中取价值最高者放入背包. 若背包剩余容量=0或物体全部装入背包为止
这种策略下的量度是已装入物品的累计效益值与所用 容量之比。
(v2/w2 , v3/w3 , v1/w1 )=(24/15,15/10, 25/18) 先装入重量为15的物品2,在装入重量为5的物品3, ∑pixi =24+15*5/10=31.5。此结果为最优解。
算法设计与分析 > 贪心算法
[例] n=3,c=20 (v1,v2,v3)=(25,24,15),(w1,w2,w3)=(18,15,10)
[常见应用]背包问题,最小生成树,最短路径,作业调度等等 [算法优点]求解速度快,时间复杂性有较低的阶. [算法缺点]需证明是最优解.
[适用问题] 具备贪心选择和最优子结构性质的最优化问题 贪心选择性质:整体的最优解可通过一系列局部最优解达到,即
贪心选择到达。
贪心算法通常以自顶向下的方式进行,以迭代的方式作出相
精选ppt13最优化描述找一个n元向量x44背包问题knapsackproblemmax问题描述设有n个物体和一个背包物体i的重量为w1装入背包则具有价值为v目标是找到一个方案使放入背包的物体总价值最高贪心算法精选ppt141652425121502028202312031011220315算法设计与分析贪心算法精选ppt151用贪心策略求解背包问题时首先要选出最优的度量标准
贪婪算法
中国数学建模-编程交流-贪婪算法feifei7 重登录隐身用户控制面板搜索风格论坛状态论坛展区社区服务社区休闲网站首页退出>> VC++,C,Perl,Asp...编程学习,算法介绍. 我的收件箱(0)中国数学建模→学术区→编程交流→贪婪算法您是本帖的第672 个阅读者* 贴子主题:贪婪算法b等级:职业侠客文章:472积分:951门派:黑客帝国注册:2003-8-28第11 楼1.3.6 最小耗费生成树在例1 - 2及1 - 3中已考察过这个问题。
因为具有n个顶点的无向网络G的每个生成树刚好具有n-1条边,所以问题是用某种方法选择n-1条边使它们形成G的最小生成树。
至少可以采用三种不同的贪婪策略来选择这n-1条边。
这三种求解最小生成树的贪婪算法策略是:K r u s k a l算法,P r i m算法和S o l l i n算法。
1. Kruskal算法(1) 算法思想K r u s k a l算法每次选择n-1条边,所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中。
注意到所选取的边若产生环路则不可能形成一棵生成树。
Kr u s k a l算法分e 步,其中e 是网络中边的数目。
按耗费递增的顺序来考虑这e条边,每次考虑一条边。
当考虑某条边时,若将其加入到已选边的集合中会出现环路,则将其抛弃,否则,将它选入。
考察图1-12a 中的网络。
初始时没有任何边被选择。
图13-12b 显示了各节点的当前状态。
边(1 ,6)是最先选入的边,它被加入到欲构建的生成树中,得到图1 3 - 1 2 c。
下一步选择边(3,4)并将其加入树中(如图1 3 -1 2 d所示)。
然后考虑边( 2,7 ),将它加入树中并不会产生环路,于是便得到图1 3 - 1 2 e。
下一步考虑边(2,3)并将其加入树中(如图1 3 - 1 2f所示)。
在其余还未考虑的边中,(7,4)具有最小耗费,因此先考虑它,将它加入正在创建的树中会产生环路,所以将其丢弃。
贪婪算法 - 1
贪婪准则:做决策的依据. 贪婪算法:每一步,根据贪婪准则,做出一个看上去最优 的决策.
山东大学计算机科学与技术学院
数据结构
第13章
贪婪算法
7
最短路径
如图所示的有向网络,路径的长度定义为 路径所经过的各边的耗费之和。要求找一 条从初始顶点s 到达目的顶点d 的最短路 径。
8/16/2015
8
山东大学计算机科学与技术学院
数据结构
第13章
贪婪算法
18
拓扑排序问题
在很多条件下,任务的执行是连续进行的。
可根据所建议的顺序来执行。
任务序列?
山东大学计算机科学与技术学院
数据结构
第13章
贪婪算法
19
拓扑序列和拓扑排序
拓扑序列(Topological orders/topological
sequences):
数据结构 第13章 贪婪算法 24
山东大学计算机科学与技术学院
贪婪算法的正确性
定理13-2:如果图13-5算法失败,则有向图含有环路
证明:
注意到当失败时|V|<n,且没有候选顶点能加入V中,因此至 少有一个顶点q1不在V中, 有向图中必包含边(q2,q1)且q2不在V中,否则,q1是可加入 V的候选顶点。 同样,必有边(q3, q2 )使得q3不在V中,若q3= q1,则q1 q2 q3是有向图中的一个环路; 若q3≠ q1 ,则必存在q4使( q4, q3)是有向图的边且q4不在V 中,否则,q3便是V的一个候选顶点。 若q4为q1, q2, q3中的任何一个,则又可知有向图含有环, 否则,因为有向图具有有限个顶点数n,继续利用上述方法, 最后总能找到一个环路。
贪婪算法(贪心算法)
贪婪算法(贪⼼算法)贪⼼算法简介:@anthor:QYX 贪⼼算法是指:在每⼀步求解的步骤中,它要求“贪婪”的选择最佳操作,并希望通过⼀系列的最优选择,能够产⽣⼀个问题的(全局的)最优解。
贪⼼算法每⼀步必须满⾜⼀下条件: 1、可⾏的:即它必须满⾜问题的约束。
2、局部最优:他是当前步骤中所有可⾏选择中最佳的局部选择。
3、不可取消:即选择⼀旦做出,在算法的后⾯步骤就不可改变了。
贪⼼算法的定义:贪⼼算法是指在对问题求解时,总是做出在当前看来是最好的选择。
也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解。
贪⼼算法不是对所有问题都能得到整体最优解,关键是贪⼼策略的选择,选择的贪⼼策略必须具备⽆后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
解题的⼀般步骤是:1.建⽴数学模型来描述问题;2.把求解的问题分成若⼲个⼦问题;3.对每⼀⼦问题求解,得到⼦问题的局部最优解;4.把⼦问题的局部最优解合成原来问题的⼀个解。
如果⼤家⽐较了解动态规划,就会发现它们之间的相似之处。
最优解问题⼤部分都可以拆分成⼀个个的⼦问题,把解空间的遍历视作对⼦问题树的遍历,则以某种形式对树整个的遍历⼀遍就可以求出最优解,⼤部分情况下这是不可⾏的。
贪⼼算法和动态规划本质上是对⼦问题树的⼀种修剪,两种算法要求问题都具有的⼀个性质就是⼦问题最优性(组成最优解的每⼀个⼦问题的解,对于这个⼦问题本⾝肯定也是最优的)。
动态规划⽅法代表了这⼀类问题的⼀般解法,我们⾃底向上构造⼦问题的解,对每⼀个⼦树的根,求出下⾯每⼀个叶⼦的值,并且以其中的最优值作为⾃⾝的值,其它的值舍弃。
⽽贪⼼算法是动态规划⽅法的⼀个特例,可以证明每⼀个⼦树的根的值不取决于下⾯叶⼦的值,⽽只取决于当前问题的状况。
换句话说,不需要知道⼀个节点所有⼦树的情况,就可以求出这个节点的值。
由于贪⼼算法的这个特性,它对解空间树的遍历不需要⾃底向上,⽽只需要⾃根开始,选择最优的路,⼀直⾛到底就可以了。
第3篇 核心篇-贪婪算法
4/2
算法思想
• 为使找回的零钱的硬币数最小,不考虑找零钱的所 有各种方案,而是从最大面值的币种开始,按递减 的顺序考虑各币种,先尽量用大面值的币种,只当 不足大面值币种的金额才会去考虑下一种较小面值 的币种,这就是在采用贪婪法。 • 这种方法在这里之所以总是最优,是因为银行对其 发行的硬币种类和硬币面值的巧妙安排。 • 如果只有面值分别为1,5和11单位的硬币,而希望 找回总额为15单位的硬币,按贪婪算法,应找1个11 单位面值的硬币和4个1单位面值的硬币,共找回5个 硬币。但最优的解答应是3个5单位面值的硬币。
3
3/2
引例 [找零钱]
• 一个小孩买了价值少于1美元的糖,并将1美元的 钱交给售货员。售货员希望用数目最少的硬币找 给小孩。 • 假设提供了数目不限的面值为2 5美分、1 0美分、 5美分、及1美分的硬币。 • 售货员分步骤组成要找的零钱数,每次加入一个 硬币。选择硬币时所采用的贪婪准则如下: 每一次选择应使零钱数尽量增大。为保证解 法的可行性(即:所给的零钱等于要找的零钱 数),所选择的硬币不应使零钱总数超过最终所 需的数目。
活动都要求使用同一资源,如演讲会场等,而在同一 时间内只有一个活动能使用这一资源。每个活动i都有 一个要求使用该资源的起始时间begin[i]和一个结束时间 end[i],且begin[i] <end[i] 。如果选择了活动i,则它在半开 时间区间[begin[i], end[i])内占用资源。若区间[begin[i], end[i])与区间[begin[j], end[j])不相交,则称活动i与活动j 是相容的。也就是说,当begin[i]≥end[j]或begin[j]≥end[i] 时,活动i与活动j相容。
27
27/2
Chapter13-贪婪算法
InDegree[u]--;
if (!InDegree[u]) S.Add(u);
u = NextVertex(w);
}
} 2021/7/20
精选课件
DeactivatePos(); delete [] InDegree; return (i == n); }
邻接矩阵:Θ(n2) 邻接链表:Θ(n+e)
2021/7/20
精选课件
LOGO
13
数据结构的选择
LOGO
输出序列V:用一维数组来描述;
用一个栈来保存加入V的候选顶点;
另有一个一维数组InDegree,InDegree[j]表示与 顶点j相连的节点i的数目,其中顶点i不是V中的成员, 它们之间的有向图的边表示为(i,j)。
2021/7/20
精选课件
20
边上权值非负情形的单源最短路径问题 LOGO
问题针对有向图 G,每条边都有一个非负的长 度(耗费)a[i][j],路径的长度即为此路径所经过 的边的长度之和。
【问题描述】给定一个带权有向图D和源点v,求 从v到D中其余各顶点的最短路径——单源点的最 短路径。
2021/7/20
精选课件
21
精选课件
18
3 1
课后练习
LOGO
对于如图所示的图,写出它的
四种不同的拓扑序列。
7
5
2
6
4
2021/7/20
精选课件
19
2、单源点最短路径
1、源点:路径上的第一个顶点; 2、终点:路径上的最后一个顶点;
LOGO
3、最短路径:从源点到终点所经过的边上的权 值之和为最小的路径。
2021/7/20
贪婪算法(GreedyAlgorithm)
贪婪算法(贪婪算法(GreedyAlgorithm)Greedy Algorithm《数据结构与算法——C语⾔描述》图论涉及的三个贪婪算法1. Dijkstra 算法2. Prim 算法3. Kruskal 算法Greedy 经典问题:coin change在每⼀个阶段,可以认为所作决定是好的,⽽不考虑将来的后果。
如果不要求最对最佳答案,那么有时⽤简单的贪婪算法⽣成近似答案,⽽不是使⽤⼀般说来产⽣准确答案所需的复杂算法。
所有的调度问题,或者是NP-完全的,或者是贪婪算法可解的。
NP-完全性:计算复杂性理论中的⼀个重要概念,它表征某些问题的固有复杂度。
⼀旦确定⼀类问题具有NP完全性时,就可知道这类问题实际上是具有相当复杂程度的困难问题。
贪⼼算法是⼀类算法的统称10.1.1 ⼀个简单的调度问题将最后完成时间最⼩化这个问题是NP-完全的。
因此,将++最后完成时间最⼩化++显然⽐++平均完成时间最⼩++化困难得多。
10.1.2 Huffman 编码让字符代码的长度从字符到字符是变化不等,同时保证经常出现的字符其代码更短。
最优编码的树将具有的性质:所有结点或者是树叶,或者有两个⼉⼦。
字符代码的长度是否不相同并不要紧,只要没有字符代码是别的字符代码的前缀即可。
基本的问题:找到总价值(编码总长度)最⼩的满⼆叉树。
Huffman 算法因为每⼀次合并都不进⾏全局的考虑,只是选择两棵最⼩的树,所以该算法是贪⼼算法。
由此可见,贪⼼算法是⼀类算法的统称。
在⽂件压缩这样的应⽤中,实际上⼏乎所有的运⾏时间都花费在读⼊⽂件和写⽂件所需的磁盘 I/O 上。
伪代码1. ⽣成 Huffman 树while(minHeap.size() > 1){tree->left = minHeap.get()tree->right = minHeap.get()tree->frequence = tree->left->frequence + tree->right->frequenceminHeap.insert(tree);}huffmanTree = minHeap.get();2. 从 Huffman 树到 Huffman 编码(递归调⽤)字符集⼀般是常数的数量级,所以这⾥使⽤递归虽不是最优解,但⾜矣解此题。
贪婪法
2
1 贪婪算法的思想
贪婪算法(贪心算法 的根本思想 贪婪算法 贪心算法)的根本思想: 贪心算法 的根本思想: 求方法使生产某产品所花费的时间最少; 例:求方法使生产某产品所花费的时间最少; 最直接的方法:枚举; 最直接的方法:枚举; 高效一点的方法: 高效一点的方法:在生产该产品的每一道工序上都选择 最省时的方法; 最省时的方法; 以逐步的局部最优,达到最终的全局最优。 以逐步的局部最优,达到最终的全局最优。 贪婪算法通过一系列的局部选择来得到一个问题的解。所 贪婪算法通过一系列的局部选择来得到一个问题的解。 作的每一个选择都是当前状态下“最优”的选择。 作的每一个选择都是当前状态下“最优”的选择。 如何判断“当前最优” 如何判断“当前最优”? 要依照某种策略。策略“只顾眼前,不管将来”,称之 要依照某种策略。策略“只顾眼前,不管将来” 贪婪策略” 为“贪婪策略”。 贪婪算法没有固定的算法框架,算法设计的关键是贪婪策 贪婪算法没有固定的算法框架, 略的选择。 略的选择。 贪婪算法能否得到最优解? 贪婪算法能否得到最优解?
6
问题的形式描述
目标函数: 目标函数:
1≤ i ≤ n
∑px
i
i
约束条件: 约束条件:
1≤i ≤ n
∑w xBiblioteka i i≤M0 ≤ xi ≤ 1, pi > 0, wi > 0,1 ≤ i ≤ n
满足上述约束条件的任一集合 任一集合(x 可 行 解:满足上述约束条件的任一集合 1,x2,…,xn) 都是问题 的一个可行解——可行解可能为多个。 可行解可能为多个。 的一个可行解 可行解可能为多个 称为问题的一个解向量 (x1,x2,…,xn)称为问题的一个解向量 称为问题的一个 最 优 解:能够使目标函数取最大值的可行解是问题的 能够使目标函数取最大值的可行解是问题的 最大值 最优解——最优解也可能为多个。 最优解也可能为多个。 最优解 最优解也可能为多个
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
LOGO
C8
C1 C3
C9 C7
C4
C2
C6
C5
2020/9/17
.
7
检测有向环的方法——拓扑排序
LOGO
检测有向环的一种方法是对AOV网络构造它的拓扑有 序序列。
——即将各个顶点 (代表各个活动)排列成一个线性 有序的序列,使得AOV网络中所有应存在的前驱和后继 关系都能得到满足。
这种构造AOV网络全部顶点的拓扑有序序列的运算就 叫做拓扑排序。
2020/9/17
.
LOGO
13
数据结构的选择
LOGO
输出序列V:用一维数组来描述;
用一个栈来保存加入V的候选顶点;
另有一个一维数组InDegree,InDegree[j]表示与 顶点j相连的节点i的数目,其中顶点i不是V中的成员, 它们之间的有向图的边表示为(i,j)。
2020/9/17
.
C1
C2
C1
C2
C3
2020/9/17
C5
C3
.
C5
10
拓扑排序的过程(续)
LOGO
C1
C2
C1
C5
C5
C5
最后得到的拓扑有序序列为 C4 , C0 , C3 , C2 , C1 , C5 。满足 图中给出的所有前驱和后继关系,对于本来没有这种关系的顶 点,如C4和C2,也排出了先后次序关系。
2020/9/17
▪ Kruskal算法 ▪ Prime算法 ▪ Sollin算法
2020/9/17
.
3
1、拓扑排序
LOGO
❖ DAG图:有向无环图 ❖ 几乎所有的工程(project)都可分为若干个称作
“活动”的子工程,并且这些子工程之间通常受 着一定条件的约束,例如其中某些子工程必须在 另一些子工程完成之后才能开始
InDegree[u]--;
if (!InDegree[u]) S.Add(u);
u = NextVertex(w);
}
} 2020/9/17
.
DeactivatePos(); delete [] InDegree; return (i == n); }
邻接矩阵:Θ(n2) 邻接链表:Θ(n+e)
16
Chapter13 贪婪算法
LOGO
2020/9/17
.
1
内容提要
❖13.1 示例问题提出 ❖13.2 贪婪算法的思想 ❖13.3 贪婪算法的应用
▪ 货箱装船 ▪ 拓扑排序 ▪ 单源最短路径 ▪ 最小耗费生成树
2020/9/17
.
LOGO
2
贪婪算法应用
LOGO
❖拓扑排序 ❖单源点最短路径——Dijkstra算法 ❖最小耗费生成树
❖ 对整个工程和系统,主要关心两方面的问题:
▪ 工程能否顺利进行——拓扑排序;
▪ 完成整个工程所必须的最短时间——求关键路 径
2020/9/17
.
4
顶点表示活动的网络 (Activity On Vertices: AOV 网络) LOGO
用有向图表示一个工程。在这种有向图中, • 用顶点表示活动, • 有向边<Vi, Vj>表示活动Vi 必须先于活动Vj 进行。 —— 顶点表示活动的网络(Activity On Vertices), AOV 网络。
14
bool Network::Topological(int v[]) {
LOGO
int n = Vertices();
int *InDegree = new int [n+1]; InitializePos(); for (int i = 1; i <= n; i++) InDegree[i] = 0;
全部顶点均已输出,拓扑有序序列形成,拓扑排序完成; 或图中还有未输出的顶点,但已跳出处理循环——这说明图 中还剩下一些顶点,它们都有直接前驱,再也找不到没有前 驱的顶点了。这时AOV网络中必定存在有向环。
2020/9/17
.
9
拓扑排序的过程
LOGO
C0
C1
C2
C0
C1
C2
C3
C4
C5
C3
C4
C5
C0
如果通过拓扑排序能将AOV网络的所有顶点都排入一 个拓扑有序的序列中,则该AOV网络中必定不会出现有向 环;反之,说明AOV网络存在有向环,工程不可行。
2020/9/17
.
8
拓扑排序方法
(1)输入AOV网络。令 n 为顶点个数。
LOGO
(2)在AOV网络中选一个没有直接前驱的顶点, 并输出之;
(3)从图中删去该顶点, 同时删去所有它发出的有向边; 重复以上(2)、(3)步, 直到
.
11
课堂练习:学生选课的拓扑序列
C8
C1 C3
C9 C7
C4
C2
C6
C5
LOGO
2020/9/17
.
12
拓扑排序用贪婪算法实现
设n是有向图中的顶点数 设V是一个空序列 while(true) {
设w不存在入边(v,w),其中顶点v不在V中 如果没有这样的w,break。 把w添加到V的尾部 } if(V中的顶点个数少于n)算法失败 else V是一个拓扑序列
for (i = 1; i <= n; i++) 首先计算每个顶点的入度
{
int u = Begin(i);
while (u) {
InDegree[u]++;
邻接矩阵:Θ(n2) 邻接链表:Θ(n+e)
20/9/17
.
15
LinkedStack<int> S;
课程代号
C1 C2 C3 C4 C5 C6 C7 C8 C9
课程名称 高等数学 程序设计基础 离散数学 数据结构 高级语言程序设计 编译方法 操作系统 普通物理 计算机原理
先修课程
C1, C2 C3, C2 C2 C5, C4 C4, C9 C1 C8
2020/9/17
.
LOGO
6
表示课程之间优先关系的有向图
补充:AOE网络
LOGO
❖用边表示活动的网络
在AOV网络中,如果活动Vi 必须在活动Vj 之前进行,则 存在有向边<Vi, Vj>, AOV网络中不能出现有向回路,即有 向环。
在AOV网络中如果出现了有向环,则意味着某项活动应 以自己作为先决条件。
对给定的AOV网络,必须先判断它是否存在有向环。
2020/9/17
.
5
AOV 网络示例:选课问题
for (i = 1; i <= n; i++) if (!InDegree[i]) S.Add(i); 入度为0的顶点入栈
LOGO
i = 0;
while (!S.IsEmpty())
{
int w;
S.Delete(w);
v[i++] = w;
int u = Begin(w);
while (u)
{ 删除并修改关联顶点的入度