第十六讲 贪心算法

合集下载

算法导论-贪心算法

算法导论-贪心算法
动态规划是一种通过将问题分解为子问题并存储子问 题的解来避免重复计算的技术。
贪心算法可以看作是动态规划的一种特例,其中只保 留了与当前状态和当前选择相关的子问题的解,而不
是保留所有子问题的解。
贪心算法通常在每一步选择中只考虑当前状态下的局 部最优解,而不是考虑所有可能的选择和未来的状态。
贪心算法的经述 • 贪心算法的基本思想 • 贪心算法的经典问题 • 贪心算法的实现与优化 • 贪心算法的性能分析 • 总结与展望
贪心算法概述
01
定义与特点
定义
贪心算法是一种在每一步选择中都采取当前情况下最好或最优(即最有利)的 选择,从而希望导致结果是最好或最优的算法。
无法保证全局最优解
贪心算法可能只得到局部最优解,而非全局最 优解。
缺乏理论支持
贪心算法的理论基础尚不完备,难以对所有情况做出准确预测。
贪心算法与其他算法的比较
与动态规划算法比较
动态规划算法通过将问题分解为子问题来求解,适合处理具有重叠子问题和最优子结构的问题;而贪 心算法则是每一步都选择当前最优的选择,希望这样的局部最优选择能够导致全局最优解。
法的时间复杂度。
需要注意的是,贪心算法并不总是能够提供最优解,因此在实际应用中, 需要权衡时间复杂度和解的质量。
空间复杂度分析
贪心算法的空间复杂度主要取决于算法 的存储需求。在某些情况下,贪心算法 可能需要大量的存储空间来存储中间结
果或数据结构。
在分析贪心算法的空间复杂度时,需要 考虑算法所需的存储空间和存储结构的 复杂性。通过将每个存储需求的空间复 杂度相加,可以得出整个算法的空间复
与分治算法比较
分治算法是将问题分解为若干个子问题,然后递归地求解这些子问题,再将子问题的解合并起来得到 原问题的解;而贪心算法是在每一步都做出在当前状态下最好或最优(即最有利)的选择,希望这样 的局部最优选择能够导致全局最优解。

贪心算法Greedy

贪心算法Greedy
具体算法可描述如下页:
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++) {
例如,设7个独立作业{1,2,3,4,5,6,7}由3台机 器M1,M2和M3加工处理。各作业所需的处理时 间分别为{2,14,4,16,6,5,3}。按算法greedy产生 的作业调度如下图所示,所需的加工时间为17。
例2.背包问题
0-1背包问题:
给定n种物品和一个背包。物品i的重量是Wi,其价值为 Vi,背包的容量为C。应如何选择装入背包的物品,使得 装入背包中物品的总价值最大?
在选择装入背包的物品时,对每种物品i只有2种选择,即装入 背包或不装入背包。不能将物品i装入背包多次,也不能只装入部 分的物品i。
背包问题:
template<class Type> void Loading(int x[], Type w[], Type c, int n) {
int *t = new int [n+1]; Sort(w, t, n); for (int i = 1; i <= n; i++) x[i] = 0; for (int i = 1; i <= n && w[t[i]] <= c; i++) {x[t[i]] = 1; c -= w[t[i]];} }
动态规划算法通常以自底向上的方式解各子问题,而 贪心算法则通常以自顶向下的方式进行,以迭代的方式 作出相继的贪心选择,每作一次贪心选择就将所求问题 简化为规模更小的子问题。

贪心算法的图文讲解

贪心算法的图文讲解

总结
• 在对问题求解时,会选择当前看起来最有希望成功的边(任务) 。一旦做出决定,它就不会再重新考虑,也不会关心后面会引发 什么情况。也就是说,不从整体最优上加以考虑,它所做出的是 在某种意义上的局部最优解。 • 贪心算法是一种能够得到某种度量意义下的最优解的分级处理方 法,通过一系列的选择来得到一个问题的解,而它所做的每一次 选择都是当前状态下某种意义的最好选择,即贪心选择。即希望 通过问题的局部最优解来求出整个问题的最优解。这种策略是一 种很简洁的方法,对许多问题它能产生整体最优解,但不能保证 总是有效,因为它不是对所有问题都能得到整体最优解,只能说 其解必然是最优解的很好近似值
对于这个问题我们有以下几种情况:设加油次数为k,每个加油 站间距离为a[i];i=0,1,2,3……n (1)始点到终点的距离小于N,则加油次数k=0; (2)始点到终点的距离大于N时: A 加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n ; B 加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点; C 加油站间的距离相等,即a[i]=a[j]=L<N,则加油次数 k=n/N(n%N==0)或k=[n/N]+1(n%N!=0); D 加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过贪心 算法求解。

• • 贪心的基本思想
• 用局部解构造全局解,即从问题的某一个初始解逐步逼 近给定的目标,以尽可能快地求得更好的解。当某个算 法中的某一步不能再继续前进时,算法停止。贪心算法 思想的本质就是分处理 出一个最好的方案。 • 利用贪心策略解题,需要解决两个问题: • (1)该题是否适合于用贪心策略求解; • (2)如何选择贪心标准,以得到问题的最优/较优解。

算法_贪心算法

算法_贪心算法

猴子
• 耍小聪明策略:重量小的优先放入。 • 物品n=3,背包的载重量C=20 • 各个物品价值(v1,v2,v3)=(25,24,15)
• 各个物品的重量( w1,w2,w3)=(18,15,10)。
物品3 1 物品2 2/3
计算器 15+24*(2/3) = 31
啄木鸟
• 算盘子策略:单位重量价值高的优先放入。 • 物品n=3,背包的载重量C=20 • 各个物品的价值(v1,v2,v3)=(25,24,15) • 各个物品的重量( w1,w2,w3)=(18,15,10) • 单位价值 (v1/w1, v2/w2, v3/w3)=(1.39,1.6,1.5)
例5.2 数列极差问题
在黑板上写N个正整数排成一个数列,进行如下操作:每 一次擦去其中的两个数a和b,然后在数列中加入一个数a×b+1, 如此下去直至黑板上剩下一个数,在所有按这种操作方式最后 得到的数中,最大的记作max,最小的记作min,则该数列的 极差定义为M=max-min。 如: 对三个具体数据3,5,7讨论,可能有以下三种结果: (3*5+1)*7+1=113,(3*7+1)*5+1=111, (5*7+1)*3+1=109 结论:先运算小数据得到的是最大值,先运算大数据得到的 是最小值。
1)由设计2)、3)知,必须用两个数组同时存储初始数据。 2)求最大和最小的两个数的函数至少要返回两个数据,方便 起见用全局变量实现。 int s1,s2; main() {int j,n,a[100],b[100],max,min; printf("How mang data?"); scanf("%d",&n); printf("input these data"); for (j=1;j<=n;j=j+1) {scanf("%d",&a[j]); b[j]=a[j];} min= calculatemin(a,n); max= calculatemax(b,n); printf("max=%d,min=%d,max-min=%d", max,min,maxmin); }

贪心算法的基本框架

贪心算法的基本框架

贪心算法的基本框架什么是贪心算法贪心算法是一种常见的求解最优化问题的方法,它通过每一步选择局部最优解来达到全局最优解。

在每一步选择中,贪心算法会考虑当前状态下的最优选择,并不考虑之后的结果。

贪心算法的基本思想贪心算法的基本思想是通过局部最优解来推导全局最优解。

它不需要穷举所有可能的情况,因此通常具有较高的效率。

贪心算法的基本框架贪心算法通常包含以下几个步骤:1.定义问题:明确问题要求和目标。

2.确定贪心策略:选择当前状态下局部最优解。

3.判断是否满足问题要求:判断当前状态是否满足问题要求。

4.更新状态:根据当前状态和选择更新问题状态。

5.终止条件:判断是否达到终止条件,如果达到,则输出结果;否则返回第2步。

贪心算法的应用场景贪心算法适用于一些特定类型的问题,例如:•最小生成树问题:如Prim和Kruskal算法。

•最短路径问题:如Dijkstra和Bellman-Ford算法。

•区间调度问题:如活动选择问题。

•背包问题的近似算法。

贪心算法的优缺点贪心算法的优点是简单、高效,适用于一些特定类型的问题。

但是,贪心算法并不是万能的,它只能求解满足贪心选择性质和最优子结构性质的问题。

对于某些问题,贪心算法可能得到次优解或者无解。

贪心算法与动态规划的比较与动态规划相比,贪心算法更加简单、高效。

它不需要穷举所有可能的情况,并且每一步只需要考虑当前状态下的最优选择。

但是,贪心算法不能保证找到全局最优解,而动态规划可以。

贪心算法实例:找零钱问题假设有1元、5元、10元、20元和50元面额的纸币,现在要找给客户66元,请问如何用最少数量的纸币找零?解题思路首先,我们可以观察到每次找零都应该尽量使用面额大的纸币。

因此,我们可以按照从大到小排列纸币面额,并依次尝试使用最大面额的纸币进行找零。

算法实现def change_money(amount):denominations = [50, 20, 10, 5, 1]count = 0for denomination in denominations:if amount >= denomination:count += amount // denominationamount %= denominationreturn countamount = 66min_count = change_money(amount)print(f"The minimum number of banknotes to make change for {amount} yuan is {min_count}.")算法分析在上述算法中,我们首先定义了纸币的面额,并初始化找零所需的最小纸币数量为0。

贪心算法数学建模表达式

贪心算法数学建模表达式

贪心算法是一种常用的解决优化问题的方法,它通过每一步选择当前最优解来逐步构建问题的最优解。

在数学建模中,贪心算法可以用数学表达式来描述和求解问题。

首先,我们需要定义问题的目标函数。

目标函数是一个数学表达式,用来衡量问题的解的优劣。

例如,假设我们要解决一个任务调度问题,目标是最小化总任务完成时间。

那么,可以定义目标函数为任务完成时间的总和。

接下来,我们需要定义问题的约束条件。

约束条件是问题中的限制条件,用来限定解的可行性。

在任务调度问题中,约束条件可以是任务的截止时间、任务的执行顺序等。

然后,我们可以利用贪心算法来求解问题。

贪心算法的核心思想是每一步选择当前最优解,以期望最终得到全局最优解。

在数学建模中,可以通过数学表达式来描述每一步的选择。

例如,在任务调度问题中,可以通过比较任务的截止时间和当前时间来选择最优的任务进行调度。

在贪心算法中,我们还需要证明贪心选择的正确性。

这可以通过数学推导和分析来完成。

例如,在任务调度问题中,我们可以证明贪心选择每次选择最早截止时间的任务是正确的,即不会导致最终解的劣化。

最后,我们需要根据贪心选择的结果来构建问题的最优解。

在数学建模中,可以将贪心选择的结果转化为数学表达式,以得到问题的最优解。

例如,在任务调度问题中,可以将贪心选择的结果表示为任务的执行顺序和完成时间,以得到最优的任务调度方案。

综上所述,贪心算法在数学建模中可以通过数学表达式来描述和求解问题。

通过定义目标函数和约束条件,利用贪心算法进行选择,并根据选择结果构建最优解,可以解决各种优化问题。

在实际应用中,贪心算法在任务调度、资源分配、路径规划等领域具有广泛的应用价值。

通过数学建模和贪心算法的结合,我们可以更好地分析和解决实际问题,提高问题的效率和质量。

贪心算法的原理是

贪心算法的原理是

贪心算法的原理是
贪心算法是一种求解最优问题的常用算法思想,其基本原理是在每一步选择中都采取当前状态下最优的选择,从而希望最终得到全局最优解。

贪心算法的主要特点是局部最优策略同时也是全局最优策略。

贪心算法通常包含以下步骤:
1. 确定问题的最优子结构:即问题的整体最优解可以通过一系列局部最优解来达到。

这是贪心算法的基础,也是保证贪心选择性质的关键。

2. 构造贪心选择:通过局部最优策略来构造每一步的最优解,不考虑前面步骤的选择是否能够达到全局最优。

3. 解决子问题:将子问题缩小,通过递归或迭代的方式求解。

4. 合并子问题的解:将子问题的解合并起来,形成原问题的解。

贪心算法的正确性依赖于贪心选择性质和最优子结构性质。

贪心选择性质指的是,通过局部最优解就可以推导出全局最优解。

最优子结构性质指的是,问题的整体最优解可以通过一系列局部最优解来达到。

贪心算法的应用广泛,常见的问题包括:
1. 找零钱问题:给定一些面额不同的硬币和一个总金额,如何用最少数量的硬币凑出总金额。

2. 区间调度问题:给定一些活动的开始时间和结束时间,如何安排活动使得参加的活动数量最多。

3. Huffman编码问题:如何用最短的编码长度来表示一个给定概率分布的字符集。

虽然贪心算法通常能够在很短的时间内找到一个解,但并不是所有问题都适合使用贪心算法。

贪心算法不能保证得到最优解,只能保证得到一个近似最优解。

因此,在使用贪心算法解决问题时需要根据具体问题的特性来判断是否适合使用贪心算法。

贪婪算法(贪心算法)

贪婪算法(贪心算法)

贪婪算法(贪⼼算法)贪⼼算法简介:@anthor:QYX 贪⼼算法是指:在每⼀步求解的步骤中,它要求“贪婪”的选择最佳操作,并希望通过⼀系列的最优选择,能够产⽣⼀个问题的(全局的)最优解。

贪⼼算法每⼀步必须满⾜⼀下条件: 1、可⾏的:即它必须满⾜问题的约束。

2、局部最优:他是当前步骤中所有可⾏选择中最佳的局部选择。

3、不可取消:即选择⼀旦做出,在算法的后⾯步骤就不可改变了。

贪⼼算法的定义:贪⼼算法是指在对问题求解时,总是做出在当前看来是最好的选择。

也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解。

贪⼼算法不是对所有问题都能得到整体最优解,关键是贪⼼策略的选择,选择的贪⼼策略必须具备⽆后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

解题的⼀般步骤是:1.建⽴数学模型来描述问题;2.把求解的问题分成若⼲个⼦问题;3.对每⼀⼦问题求解,得到⼦问题的局部最优解;4.把⼦问题的局部最优解合成原来问题的⼀个解。

如果⼤家⽐较了解动态规划,就会发现它们之间的相似之处。

最优解问题⼤部分都可以拆分成⼀个个的⼦问题,把解空间的遍历视作对⼦问题树的遍历,则以某种形式对树整个的遍历⼀遍就可以求出最优解,⼤部分情况下这是不可⾏的。

贪⼼算法和动态规划本质上是对⼦问题树的⼀种修剪,两种算法要求问题都具有的⼀个性质就是⼦问题最优性(组成最优解的每⼀个⼦问题的解,对于这个⼦问题本⾝肯定也是最优的)。

动态规划⽅法代表了这⼀类问题的⼀般解法,我们⾃底向上构造⼦问题的解,对每⼀个⼦树的根,求出下⾯每⼀个叶⼦的值,并且以其中的最优值作为⾃⾝的值,其它的值舍弃。

⽽贪⼼算法是动态规划⽅法的⼀个特例,可以证明每⼀个⼦树的根的值不取决于下⾯叶⼦的值,⽽只取决于当前问题的状况。

换句话说,不需要知道⼀个节点所有⼦树的情况,就可以求出这个节点的值。

由于贪⼼算法的这个特性,它对解空间树的遍历不需要⾃底向上,⽽只需要⾃根开始,选择最优的路,⼀直⾛到底就可以了。

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

贪心算法的基本思想:适用于求解最优化问题的算法往往包含一系列步骤,每一步都有一组选择;贪心算法总是作出在当前看来是最好的选择;贪心算法并不从整体最优上加以考虑,它所作出的选择只是在某种意义上的局部最优选择;贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解;在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似;与动态规划方法相比,贪心算法更简单,更直接。

活动安排问题:设有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相容;目标:要在所给的活动集合中选出最大的相容活动子集合。

贪心策略求解方案:将活动按照结束时间的增序f1≤ f2≤…≤ fn-1排列;一开始选择活动1,然后依次检查后面的活动i是否与前面已选择的活动相容,若相容,则将活动i加入到已选择的活动集合中;若不相容,则继续检查下一活动与已选择活动的相容性;由于活动已按结束时间排序,设刚加入已选择活动集合的活动是j,因此只需检查活动i的是否与j 相容;也就是检查是否满足si≥fj,若满足,则活动i与j相容贪心体现在总是选择具有最早完成时间的相容活动。

设待安排的11个活动的开始时间和结束时间已按结束时间的增序排列:i 1 2 3 4 5 6 7 8 9 10 11S[i] 1 3 0 5 3 5 6 8 8 2 12f[i] 4 5 6 7 8 9 10 11 12 13 14GREEDY-ACTIVITY-SELECTOR(s, f)1 n ← length[s]2 A ← {activity 1}3 j← 14 for i ← 2 to n5 do if si≥ fj6 then A ← A ∪ {activity i}7 j← i8 return A复杂度分析:如果已经排序,算法的时间复杂度为Θ(n);如果事先没有按照结束时间增序排列,排序需O(nlgn);贪心算法可以获得该问题的整体最优解可证明:1.活动安排问题有一个最优解以贪心选择开始;2.做出贪心选择之后,原问题简化为比原问题更小的但与原问题形式相同的子问题。

贪心算法的基本要素:贪心算法通过做一系列的选择来给出某一问题的最优解。

它所作出的每一个选择当前状态下的最好选择(局部),即贪心选择;这种贪心选择并不总能产生最优解,但对于一些问题,比如活动安排问题,可以给出最优解;可以根据下列步骤设计贪心算法:将最优化问题转化为这样的一个问题,即先做出选择,再解决剩下的一个子问题;证明原问题总有一个最优解是做贪心选择得到的,从而说明贪心选择的安全说明在做出贪心选择之后,子问题的最优解与所作出的贪心选择联合起来,可以得出原问题的一个最优解。

许多可以用贪心算法求解的问题,具备以下两个性质:贪心选择性质、最优子结构性质。

贪心选择性质:是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到;这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别;动态规划算法通常以自底向上的方式解各子问题,贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。

最优子结构性质:当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质;问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。

0-1背包问题给定n种物品和一个背包。

物品i的重量是Wi,其价值为Vi,背包的容量为C。

应如何选择装入背包的物品,使得装入背包中物品的总价值最大?限制:在选择装入背包的物品时,对每种物品i只有2种选择,即装入背包或不装入背包。

不能将物品i装入背包多次,也不能只装入部分的物品i。

背包问题与0-1背包问题类似,所不同的是在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n。

0-1背包问题和背包问题的求解分析这2类问题都具有最优子结构性质,极为相似,但背包问题可以用贪心算法求解;而0-1背包问题却不能用贪心算法求解。

用贪心算法解背包问题的基本步骤:首先计算每种物品单位重量的价值Vi/Wi;然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包;若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包;依此策略一直地进行下去,直到背包装满为止。

对于0-1背包问题,贪心选择不能得到最优解:因为在这种情况下,它无法保证最终能将背包装满,部分闲置的背包空间使单位重量背包空间的价值降低。

事实上,在考虑0-1背包问题时,应比较选择该物品和不选择该物品所导致的最终方案,然后再作出最好选择。

由此就导出许多互相重叠的子问题(子问题重叠),这正是该问题可用动态规划算法求解的重要特征。

最优装载问题:有一批集装箱要装上一艘载重量为c的轮船。

其中集装箱i的重量为Wi。

最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。

算法:最优装载问题可用贪心算法求解,采用重量最轻者先装的贪心选择策略,可产生最优装载问题的最优解。

贪心算法的重要实例几个重要的图算法单源最短路径· Dijkstra算法;最小生成树· Prim算法· Kruskal算法单源最短路径 Dijkstra算法单源最短路径问题:给定带权有向图G =(V,E),其中每条边的权是非负实数,给定V中的一个顶点,称为源。

要求计算从源到所有其他各顶点的最短路长度(这里路的长度是指路上各边权之和)。

基本思想:设置顶点集合S,初始时,S中仅含有源,此后不断作贪心选择来扩充这个集合;一个顶点属于集合S当且仅当从源到该顶点的最短路径;长度已知,设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度;Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist作必要的修改;一旦S包含了所有V中顶点,dist 就记录了从源到所有其他顶点之间的最短路径长度。

贪心策略:因为Dijkstra算法总是在V-S中选择“最近”(具有最短特殊路长度)的顶点,所以说Dijkstra算法使用了贪心策略。

实例,源点1:实例:Dijkstra算法的计算过程:迭代S u dist[2] dist[3] dist[4] dist[5]初始{1} - 10 maxint 30 1001 {1,2}2 10 60 30 1002 {1,2,4} 4 10 50 30 903 {1,2,4,3} 3 10 50 30 604 {1,2,4,3,5}5 10 50 30 60分析贪心策略体现在对V-S中的点的选择上时间复杂度:对于具有n个顶点和e条边的带权有向图,如果用带权邻接矩阵表示这个图,O(n2)。

最小生成树:设G =(V,E)是无向连通带权图,即一个网络。

E中每条边(v,w)的权为c[v][w],如果G的子图G’是一棵包含G的所有顶点的树,则称G’为G的生成树。

生成树上各边权的总和为该生成树的耗费。

在G的所有生成树中,耗费最小的生成树,称为G的最小生成树。

网络的最小生成树在实际中有广泛应用例如,在设计通信网络时,用图的顶点表示城市,用边(v,w)的权c[v][w]表示建立城市v和城市w之间的通信线路所需的费用。

最小生成树就给出了建立通信网络的最经济的方案。

性质:设G=(V,E)是连通带权图,U是V的真子集。

如果(u,v)∈E,且u∈U,v∈V-U,且在所有这样的边中,(u,v)的权c[u][v]最小,那么一定存在G的一棵最小生成树,它以(u,v)为其中一条边。

用贪心算法设计策略可以设计出构造最小生成树的有效算法;构造最小生成树的Prim 算法和Kruskal算法用到了以上性质。

最小生成树 Prim算法:设G=(V,E)是连通带权图,V={1,2,…,n}Prim算法的基本思想:首先置S={1},然后,只要S是V的真子集,就作如下的贪心选择:选取满足条件i∈S,j ∈V-S,且c[i][j]最小的边,将顶点j添加到S中。

这个过程一直进行到S=V时为止;在这个过程中选取到的所有边恰好构成G的一棵最小生成树。

Prim算法求解实例:在上述Prim算法中,还应当考虑如何有效地找出满足条件i∈S,j∈V-S,且权c[i][j]最小的边(i,j),实现这个目的的较简单的办法是设置2个数组closest和lowcost,closest[j]是j在S中的邻接顶点,它与j在S中的其它邻接顶点k相比有c[j][closest[j]]≤c[j][k],lowcost[j]的值就是c[j][closest[j]]。

在Prim算法执行过程中,先找出V-S中使lowcost值最小的顶点j,然后根据数组closest 选取边(j,closest[j]),最后将j添加到S中,并对closest和lowcost作必要的修改用这个办法实现的Prim算法所需的时间复杂度为O(n2)。

最小生成树 Kruskal算法的基本思想是:首先将G的n个顶点看成n个孤立的连通分支。

将所有的边按权从小到大排序;然后从第一条边开始,依边权递增的顺序查看每一条边,并按下述方法连接2个不同的连通分支:当查看到第k条边(v,w)时,如果端点v和w分别是当前2个不同的连通分支T1和T2中的顶点时,就用边(v,w)将T1和T2连接成一个连通分支,然后继续查看第k+1条边;如果端点v和w在当前的同一个连通分支中,就直接再查看第k+1条边这个过程一直进行到只剩下一个连通分支时为止。

Kruskal算法的贪心策略:将图中的边按权值由小到大排序,由小到大顺序选取各条边,若选某边后不形成回路,则将其保留作为树的一条边。

相关文档
最新文档