【机器学习|数学基础】Mathematics for Machine Learning系列之图论(6):生成树算法

398 阅读4分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”

@TOC

在这里插入图片描述

前言

Hello!小伙伴! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~   自我介绍 ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,有幸拿过一些国奖、省奖...已保研。目前正在学习C++/Linux/Python 学习经验:扎实基础 + 多做笔记 + 多敲代码 + 多思考 + 学好英语!   机器学习小白阶段 文章仅作为自己的学习笔记 用于知识体系建立以及复习 知其然 知其所以然!

系列文章

【机器学习|数学基础】Mathematics for Machine Learning系列之图论(1):图的基本概念

【机器学习|数学基础】Mathematics for Machine Learning系列之图论(2):图的矩阵表示

【机器学习|数学基础】Mathematics for Machine Learning系列之图论(3):路径与连通

【机器学习|数学基础】Mathematics for Machine Learning系列之图论(4):有向图的连通性

【机器学习|数学基础】Mathematics for Machine Learning系列之图论(5):树及其性质

2.5 生成树算法

2.5.1 构造生成树的方法

求连通图的生成树的两种方法:

  • 破圈法
  • 避圈法

破圈法

  1. 从连通图GG开始,若GG中含有圈,则去掉圈上的一边
  2. GG中还有圈,再去掉圈上的一条边
  3. 重复上面步骤,直至GG中不含圈为止
  4. 最后得到的便是GG的不含圈的连通生成子图,即生成树

在这里插入图片描述

避圈法

  1. GG中任选一条边e1e_1
  2. 然后找一条不与e1e_1形成圈的边e2e_2,得到{e1,e2}\{e_1,e_2\}
  3. 再找一条不与{e1,e2}\{e_1,e_2\}形成圈的e3e_3,得到{e1,e2,e3}\{e_1,e_2,e_3\}
  4. ...
  5. 当找不到一条边不与{e1,e2,e3,...,ei}\{e_1,e_2,e_3,...,e_i\}形成圈,则G[{e1,e2,e3,...,ei}]G[\{e_1,e_2,e_3,...,e_i\}]GG的生成树

在这里插入图片描述

2.5.2 最小生成树算法

定义2.12

(1)图GG的每条边赋予一个实数w(e)w(e),称为ee的权

此时图GG称为加权图

(2)设G1G_1GG的生成子图,则G1G_1的权定义为

w(G1)=eE(G1)w(e)w(G_1)=\sum_{e\in E(G_1)}w(e)

最小生成树

一个图的权最小的生成树称为最小生成树

权最大的生成树则称为最大生成树

Kruskal算法

T0T_0:存放生成树的边的集合,初态为ϕ\phi C(T0)C(T_0):最小生成树的权,初值为零 VSVS:部分树的顶点集的集合,其初值为:{{v1},{v2},...,{vn}}\{\{v_1\},\{v_2\},...,\{v_n\}\} 输入边的端点数组A(ε),B(ε)A(\varepsilon),B(\varepsilon)及边权数组w(ε)w(\varepsilon)

算法步骤:

  1. T0ϕ,C(T0)0,VS{{v1},{v2},...,{vn}}T_0\leftarrow\phi,\quad C(T_0)\leftarrow0,\quad VS\leftarrow\{\{v_1\},\{v_2\},...,\{v_n\}\},将EE中的边按权从小到大排成队列QQ
  2. VS=1|VS|=1,输出T0,C(T0)T_0,C(T_0),停止。 否则转下一步
  3. QQ中取出排头边(u,v)(u,v),并从QQ中删除(u,v)(u,v)
  4. u,vu,vV,SV,S的同一元素V1V_1中,则转3,否则分属两个集合V1,V2V_1,V_2,进行下一步
  5. T0T0{(u,v)},VV1V2,VSVS{V1}{V2}+V,C(T0)C(T0)+C(u,v)T_0\leftarrow T_0 \cup\{(u,v)\},\quad V \leftarrow V_1 \cup V_2,\quad VS \leftarrow VS-\{V_1\}-\{V_2\}+V,\quad C(T_0)\leftarrow C(T_0)+C(u,v),转2

步骤4 中u,vu,vV,SV,S的同一元素V1V_1中,说明若添加u,vu,v这条边会形成圈,不符合生成树条件,所以不添加,继续进行下一步


KruskalKruskal算法求下图的最小生成树

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

总结

  • 先对图中所有边按照权进行排序,从小到大
  • 从权小的边开始选,依次递增
  • 只要选择的这条边加入之前已经选好后的图中不形成圈,则可以添加该边,否则不添加

定理2.10

Kruskal算法选得的边的导出子图是最小生成树

Prim算法

L(v)L(v)vv到子树T0T_0的直接距离 输入加权连通图的带权邻接矩阵C=(Cij)n×nC=(C_{ij})_{n×n}

算法步骤:

  1. T0ϕ,C(T0)0,V={v0}T_0\leftarrow \phi, \quad C(T_0)\leftarrow0, \quad V^{'}=\{v_0\}
  2. 对每一点vVV,L(v)C(v,v0)v \in V - V{'}, \quad L(v) \leftarrow C(v, v_0)(若(v,v0)E,C(v,v0)=(v,v_0)\notin E,则C(v,v_0)=\infty
  3. V=VV^{'}= V,输出T0,C(T0)\quad T_0,C(T_0),停机。否则转下一步
  4. VVV - V^{'}中找一点uu,使得L(u)=min{L(v)v(VV)}L(u)=min\{L(v)|v\in (V - V^{'})\},并记住VV^{'}中与uu相邻的点为w,e=(w,u)w,e=(w,u)
  5. T0T0{e},C(T0)C(T0)+C(e),VV{u}T_0\leftarrow T_0\cup\{e\},\quad C(T_0)\leftarrow C(T_0)+C(e), \quad V^{'}\leftarrow V^{'}\cup \{u\}
  6. 对所有vVVv\in V - V^{'},若C(v,u)<L(u)C(v,u) < L(u),则L(v)C(v,u)L(v)\leftarrow C(v,u),否则L(v)L(v)不变
  7. 转3

PrimPrim算法求下图的最小生成树

在这里插入图片描述

在这里插入图片描述 在这里插入图片描述

总结

  • 任意在图中选一个点,构成子树T0T_0
  • 然后找距离T0T_0中所有顶点最近的一个顶点(边权最小)
  • 找到符合最近的顶点然后加入T0T_0
  • 重复第二步
  • 终止条件就是所有的顶点都添加至子树T0T_0
  • 特别注意:每一步是找距离T0T_0中所有顶点边权最小的一个顶点

定理2.11

Prim算法产生的图G(T0)G(T_0)是最小生成树

结语

说明:

  • 参考于 课本《图论》
  • 配合书中概念讲解 结合了自己的一些理解及思考

文章仅作为学习笔记,记录从0到1的一个过程

希望对您有一点点帮助,如有错误欢迎小伙伴指正

在这里插入图片描述