[算法分析笔记]最小生成树 (Minimum Spanning Tree)- 贪婪算法 (Greed Algorithm)

一. 复习图(Graph)的表示法

G r a p h G = ( V , E ) Graph G=(V,E) GraphG=(V,E)

  • V V V是所有的顶点的集合
  • E E E是所有的连接顶点的边的集合, E E E
    无向图, E E E包含的边是没有方向性的。
    有向图, E E E包含的边是有方向性的。

图的一些属性

  • ∣ E ∣ = O ( V 2 ) |E|=O(V^2) E=O(V2)
  • 如果G是连通的,即从任意两个顶点之间有通路存在, ∣ E ∣ > ∣ V ∣ − 1 |E|>|V|-1 E>V1
  • l g ( ∣ E ∣ ) = θ ( l g ( ∣ V ∣ ) ) lg(|E|) = \theta(lg(|V|)) lg(E)=θ(lg(V))

图的表示方法

  • 连接矩阵 G = ( V , E ) G=(V,E) G=(V,E), 当 V = 1 , 2 , . . . , n V={1,2,...,n} V=1,2,...,n时nxn矩阵A可以标记为
    A [ i , j ] = { 1 当 ( i , j ) ∈ E 0 当 ( i , j ) ∉ E A[i,j]=\begin{cases} 1 &\text{当} (i,j)\in E \\ 0 &\text{当} (i,j)\notin E \end{cases} A[i,j]={10(i,j)E(i,j)/E
    适合用这种方式表示的图:完全图
    在这里插入图片描述
  • 连接列表,对于顶点集合 V ∈ A V\in A VA,其连接列表可以表示为
    A d j [ 1 ] = 2 , 3 Adj[1]={2,3} Adj[1]=2,3
    A d j [ 2 ] = 3 Adj[2]={3} Adj[2]=3
    A d j [ 3 ] = Adj[3]={} Adj[3]=
    A d j [ 4 ] = 3 Adj[4]={3} Adj[4]=3
    ∣ A d j [ v ] ∣ = { 顶点的度数 无向图 顶点的出度 有向图 |Adj[v]|=\begin{cases} 顶点的度数 &\text{无向图} \\ 顶点的出度 &\text{有向图} \end{cases} Adj[v]={顶点的度数顶点的出度无向图有向图

无向图中的边可以称作握手(handshaking), ∑ v ∈ V d e g r e e ( V ) = 2 ∣ E ∣ \sum_{v\in V}degree(V)=2|E| vVdegree(V)=2∣E

二. 最小生成树(Minimum Spanning Tree - MST)

输入: 连通的无向图 G = ( V , E ) G=(V, E) G=(V,E)由有权重的边相连接, N : E → R N:E\to R N:ER
*为了简化问题,我们假设每条边的权重都不一样
输出一个包含所有顶点的最小总权重的树
W ( T ) = Σ ( u , v ) ∈ T W ( u , v ) W(T)=\Sigma_{(u,v)\in T} W(u,v) W(T)=Σ(u,v)TW(u,v)
如下图:
在这里插入图片描述

最优子结构

一棵最优子树如下图所示:
在这里插入图片描述
将上图中的 ( u , v ) (u,v) (u,v)边移出,则T被分成两棵最小生成树子树, T 1 和 T 2 T_1和T_2 T1T2。则, T 1 和 T 2 T_1和T_2 T1T2 G G G的子图 G 1 和 G 2 G1和G2 G1G2的最小生成树,其中:
G 1 = ( V 1 , E ) , V 1 是所有 T 1 的顶点 G1=(V_1,E),V_1是所有T_1的顶点 G1=(V1,E)V1是所有T1的顶点
G 2 = ( V 2 , E ) , V 1 是所有 T 2 的顶点 G2=(V_2,E),V_1是所有T_2的顶点 G2=(V2,E)V1是所有T2的顶点
证明:
如果对图 G 1 G1 G1存在 T 1 ′ T_1' T1是比 T 1 T_1 T1更优的最小生成树,那么对于图 G G G而言 T ′ = ( u , v ) ⋃ T 1 ′ ⋃ T 2 T'={(u,v)}\bigcup T_1'\bigcup T_2 T=(u,v)T1T2必然要比 T T T更优的最小生成树,与题设矛盾,故 T 1 T_1 T1必是 G 1 G_1 G1的最小生成树。
证毕

由此,我们看到最小生成树问题是可以分割成最优子结构的,我们第一想到的是动态规划。但是,实际上对于这个问题还存在一个更好的算法 - 贪婪算法(Greed Algorithm)。

三. 贪婪算法的标志

贪婪选择属性: 一个局部的最优选择也是全局的最优选择。

如果 T T T G = ( V , E ) G=(V,E) G=(V,E)的最小生成树,并且 A ⊂ V A\subset V AV,假设 ( u , v ) ∈ E (u,v)\in E (u,v)E是最小权重的边连接 A 和 V − A A和V-A AVA,那么 ( u , v ) ∈ T (u,v)\in T (u,v)T

证明:假设 ( u , v ) ∉ T (u,v)\notin T (u,v)/T,那么必然存在一条路径连接 u 和 v u和v uv,将 ( u , v ) (u,v) (u,v)和该路径上的第一条边交换,即删除该路径上的第一条边(下图中红色叉标记处),并添加 ( u , v ) (u,v) (u,v),此时出现了一棵比T更低权重和的最小生成树,与题设矛盾。
证毕
在这里插入图片描述

四. Prim‘s 算法 - 贪婪算法

基本思想:维护是一个优先队列 Q Q Q作为 V − A V-A VA的图中的所有顶点,依次输入每个顶点存在于 Q Q Q列表中且其连接边的权重值最小,并将该顶点一如最小生成树子树 A A A中。

伪代码如下:

在这里插入图片描述

最后,{(V, pi([V]}就是最后形成的最小生成树。
算法运行的过程如下图所示

  1. 第一个顶点是随机选择的
  2. 有这个点出发更新和他相连的顶点的权重,并将权重值最小的顶点加入生成树
    在这里插入图片描述
    算法效率分析
    代码的第一部分的算法复杂度是固定的n。
    代码的第二部分的算法复杂度取决于图所包含的顶点数|V|。
    代码第二部分中还包含一个循环,其算法复杂度则取决于每个顶点的度,即每个顶点的所连接的边。
    所以,总的算法复杂度是
    T i m e = θ ( V . T E x t r a c t − m i n + E . T D e c r e a s e − k e y s ) Time = \theta(V.T_{Extract-min}+E.T_{Decrease-keys}) Time=θ(V.TExtractmin+E.TDecreasekeys)
Q Q Q T E x t r a c t − m i n T_{Extract-min} TExtractmin T D e c r e a s e − k e y s T_{Decrease-keys} TDecreasekeysTotal
array O ( V ) O(V) O(V) O ( 1 ) O(1) O(1) O ( V 2 ) O(V^2) O(V2)
binary O ( l g V ) O(lgV) O(lgV) O ( l g V ) O(lgV) O(lgV) O ( E . l v V ) O(E.lvV) O(E.lvV)
fib beap O ( l g V ) a m o r t i z e d O(lgV)_{amortized} O(lgV)amortized O ( 1 ) a m o r t i z e d O(1)_{amortized} O(1)amortized O ( E + v . l g V ) O(E+v.lgV) O(E+v.lgV)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程小白的逆袭日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值