数据结构与算法 —— 最小生成树Prim算法和Kruskal算法详细图解以及python实现

目录

前言

1. 介绍

2. Prim算法(普里姆算法)

2.1 Prim算法历史

2.2 Prim算法的基本思路

2.3 Prim算法图解

2.4 Prim算法(python)实现

3. Kruskal算法(克鲁斯卡尔算法)

3.1 Kruskal算法的基本思路

3.2 Kruskal算法图解

3.3 Kruskal算法(python)实现

4. 最小生成树和最短路径的区别

5. 结尾


前言

上一章我们整理了最短路径中的 Dijkstra算法。
现在我们整理最小生成树中Prim算法(普里姆算法)和Kruskal算法(克鲁斯卡尔算法)。


1. 介绍

最小生成树也是图论中常见问题,其指的是在一个图中找到一个连通子图,使得所有节点都能够互相到达,且总权值最小。

最小生成树的例子在生活中也很常见,比如城市的公交线路系统需要规划如何走完一趟路径和是最短的,或者快递公司如何给不同住址的客户送货才能是最短的路径。


2. Prim算法(普里姆算法)

2.1 Prim算法历史

普里姆算法最初由捷克数学家沃伊捷赫·亚尔尼克于1930年发现,后来在1957年由美国计算机科学家罗伯特·普里姆独立发现,1959年艾兹格·迪科斯彻也再次发现了该算法。因此,普里姆算法在某些情况下也被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。

2.2 Prim算法的基本思路

首先选择一个起始节点,以这个节点将图分成两个集合。一个已选集合,一个未选集合。把起始节点加入已选集合。

然后从已选节点集合出发,不断选择权值最小的边连接到未选节点集合中的节点,并将其加入已选节点集合。

不断循环此过程,直到所有节点都被加入到已选节点集合中,形成最小生成树。

这就是Prim算法的基本思路。

简单来说,就是从一个点开始,不断寻找距离最短的边,将其加入最小生成树中,并将与之相连的未访问点所构成的边加入集合中,直到所有节点都被访问过为止。

2.3 Prim算法图解

在下面这个图的基础上,我们可以一步一步来分析Prim 算法的过程。

我们的目的是用此算法判断出构成最小生成树的所有边。

 

 接下来一样的操作,就不在图中标注文字解释了。

算法完成,我们得到了构成最小生成树的所有边。

2.4 Prim算法(python)实现

def prim_algorithm(graph):
    num_vertices = len(graph)
    
    # 初始化集合
    selected = set()
    selected.add(list(graph.keys())[0])  # 从第一个顶点开始
    unselected = set(graph.keys()) - selected
    
    # 初始化最小生成树结果
    minimum_spanning_tree = []

    while unselected:
        min_weight = float('inf')
        start_vertex = None
        end_vertex = None

        # 遍历已选集合中的每个顶点
        for vertex in selected:
            # 遍历未选集合中的每个顶点
            for neighbor, weight in graph[vertex].items():
                if neighbor in unselected:
                    # 找到权值最小的边
                    if min_weight > weight:
                        min_weight = weight
                        start_vertex = vertex
                        end_vertex = neighbor

        # 将找到的最小权值边添加到最小生成树结果中
        minimum_spanning_tree.append((start_vertex, end_vertex, min_weight))
        selected.add(end_vertex)
        unselected.remove(end_vertex)

    return minimum_spanning_tree

graph = {
    'A': {'B': 2, 'C': 9},
    'B': {'A': 2, 'D': 4, 'E': 8},
    'C': {'A': 9, 'E': 10, 'F': 3},
    'D': {'B': 4, 'E': 1, 'G': 5},
    'E': {'B': 8, 'C': 10, 'D': 1, 'F': 11, 'G': 6, 'H': 12},
    'F': {'C': 3, 'E': 11, 'H': 17},
    'G': {'D': 5, 'E': 6},
    'H': {'E': 12, 'F': 17},
}

result = prim_algorithm(graph)
print(result)

实现了一个上面举例子用的图,运行此程序会打印出:

[('A', 'B', 2), ('B', 'D', 4), ('D', 'E', 1), ('D', 'G', 5), ('A', 'C', 9), ('C', 'F', 3), ('E', 'H', 12)]

前两个字母表示最小生成树中的一条边,后面的数字代表这条边的权值。可以与上面的图解结合起来看。 


3. Kruskal算法(克鲁斯卡尔算法)

3.1 Kruskal算法的基本思路

该算法是先取出所有的边,按其权值从小到大的顺序排列,然后不断取出权值最小的边放入图中,一共取n-1条边(n为节点数)。但是每次放入一条边都要判断是否形成了环。如果没有形成环,则将该边纳入最小生成树中。如果形成了环,则舍弃这条边,继续取下一条边。

3.2 Kruskal算法图解

首先取出图中所有的边,并且按其权值从小到大排序。

 

此时,边的数量 = n-1,算法结束。同样也得到了一个最小生成树。 

3.3 Kruskal算法(python)实现

def find(parent, vertex):
    if parent[vertex] == vertex:
        return vertex
    return find(parent, parent[vertex])

def union(parent, rank, vertex1, vertex2):
    root1 = find(parent, vertex1)
    root2 = find(parent, vertex2)

    if root1 != root2:
        if rank[root1] > rank[root2]:
            parent[root2] = root1
        else:
            parent[root1] = root2
            if rank[root1] == rank[root2]:
                rank[root2] += 1

def kruskal_algorithm(graph):
    # 初始化结果
    minimum_spanning_tree = []

    # 初始化并查集
    parent = {vertex: vertex for vertex in graph.keys()}
    rank = {vertex: 0 for vertex in graph.keys()}

    # 获取所有的边
    edges = []
    for vertex, neighbors in graph.items():
        for neighbor, weight in neighbors.items():
            edges.append((vertex, neighbor, weight))

    # 按权值排序边
    edges.sort(key=lambda edge: edge[2])

    # 不断取出权值最小的边并判断是否形成环
    for edge in edges:
        vertex1, vertex2, weight = edge
        if find(parent, vertex1) != find(parent, vertex2):
            union(parent, rank, vertex1, vertex2)
            minimum_spanning_tree.append(edge)

        if len(minimum_spanning_tree) == len(graph) - 1:
            break

    return minimum_spanning_tree

graph = {
    'A': {'B': 2, 'C': 9},
    'B': {'A': 2, 'D': 4, 'E': 8},
    'C': {'A': 9, 'E': 10, 'F': 3},
    'D': {'B': 4, 'E': 1, 'G': 5},
    'E': {'B': 8, 'C': 10, 'D': 1, 'F': 11, 'G': 6, 'H': 12},
    'F': {'C': 3, 'E': 11, 'H': 17},
    'G': {'D': 5, 'E': 6},
    'H': {'E': 12, 'F': 17},
}

result = kruskal_algorithm(graph)
print(result)

find(parent, vertex)函数:这个函数的作用是找到给定顶点所属集合的代表元素。

union(parent, rank, vertex1, vertex2)函数:这个函数的作用是将两个不同集合合并成一个集合。 

运行上面程序之后会打印:

[('D', 'E', 1), ('A', 'B', 2), ('C', 'F', 3), ('B', 'D', 4), ('D', 'G', 5), ('A', 'C', 9), ('E', 'H', 12)]

可以发现与我们图解的答案包括Prim算法的答案是一致的。

4. 最小生成树和最短路径的区别

最小生成树和最短路径问题在目标、应用场景和解决方法上都有所不同。最小生成树关注的是连接所有顶点的最小总权值,而最短路径关注的是在带权图中找到顶点之间的最短路径。

结合图解来看会更加清晰(选择节点D为起始节点):


5. 结尾

到这里为止,我们已经整理了

图的基本结构,

深度优先搜索,广度优先搜素,

最短路径Dijkstra算法,

最小生成树Prim算法和Kruskal算法。

基本上图的内容已经整理的差不多了。下面会整理贪心算法(greedy algorithm)的内容。

如果有地方讲的不对或者大家有什么疑问,欢迎留言或者私信我!

流浪鸡蛋
关注 关注
  • 7
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
最小生成树prim算法kruskal算法
weixin_45950208的博客
03-15 369
Prim 算法思想: 从任意一顶点 v0 开始选择其最近顶点 v1 构成树 T1,再连接与 T1 最近顶点 v2 构成树 T2, 如此重复直到所有顶点均在所构成树中为止。 最小生成树(MST):权值最小的生成树。 生成树和最小生成树的应用:要连通n个城市需要n-1条边线路。可以把边上的权值解释为线路的造价。则最小生成树表示使其造价最小的生成树。 构造网的最小生成树必须解决下面两个问题: 1、尽可能选取权值小的边,但不能构成回路; 2、选取n-1条恰当的边以连通n个顶点; MST性质:假设G=(V,E)是一个
算法图解最小生成树之普里姆(Prim)算法
热门推荐
Meditation
04-30 4万+
我们在图的定义中说过,带有权值的图就是网结构。一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边。所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小。综合以上两个概念,我们可以得出:构造连通网的最小代价生成树,即最小生成树(Minimum Cost Spanning Tree)。 找连通图的最小生成树,经典的有两种
普里姆(Prim)算法
最新发布
2302_76311249的博客
09-04 1613
printf("(%d,%d) 权值%d\n", closet[k], k, lowcost[k]);j++) {//从顶点1开始找各权值中最小值及其依附顶点k。j++) {//设顶点k为下次查找的起始点。//已知图的顶点为{0,1,...,n-1},c[i][j]为边(i,j)的权,//无向图中将(v1,v2)的权值为w。//将(v1,v2)的权值为w。//顶点v1,顶点v2,权值w。
最小生成树——Prim算法Kruskal算法
yeller_Chen的博客
03-09 1516
最小生成树——Prim算法Kruskal算法 一、prim算法解析 以上图为例。 prim算法从任意顶点开始,每次都找到一个距离顶点集中距离最近的一个点,将其加入到顶点集,并把两点间的边加入到树中。直到访问完所有点,得到的就是最小生成树。 步骤: 1、从点A开始,将其加入到顶点集中,此时涉及的边有两条,[A,B]和[A, C],显然可以判断出后者距离更小,所以把C点加入到顶点集中。 2、在此顶点集中,涉及的边数增加,在所有边中继续寻找顶点集中没有的距离最短的点。这里可以找到第三个点为F。以此类推,可
算法与数据结构】—— 最小生成树Prim算法Kruskal算法
酱懵静的博客
05-05 1万+
生成树是一个连通图G的一个极小连通子图。 包含G的所有n个顶点,但只有n-1条边,并且是连通的。 生成树可由遍历过程中所经过的边组成(有多个)。一个带权连通无向图的生成树中,边的权值之和最小的那棵树叫做此图的最小生成树(唯一)。
最小生成树之普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法
糖长老莫小贝的博客
07-07 2万+
作者:STzen 链接:https://www.jianshu.com/p/683ffde4f3a3 来源:简书 最小生成树 列子引入 如图假设v0到v8表示9个村庄,现在需要在这9个村庄假设通信网络。村庄之间的数字代表村庄之间的直线距离,求用最小成本完成这9个村庄的通信网络建设。 分析 这幅图是一个带权值的图,即网结构。 所谓最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使...
无向图之最小生成树Prim算法Kruskal算法图文详解HDU1863
ChenTepiC
07-17 7764
学习算法的最好方式,我认为是应从思考一些有趣的题目开始。学习一个算法之前要知道这个算法的价值是什么。 附题:HDU 1863 最小生成树模板题  题目大意:询问你在各个村庄之间修公路,最少的花费是多少。 我们可以把“村庄"抽象成一个一个点,把”修公路的费用"抽象成连接两点的边值(权重)。 我们要求解决的是求出 把这些点(村庄)都连起来(修公路)时的所构成的树的权重总和最少(最少费用)是多少...
最小生成树Python实现)--kruskal算法prim算法、破圈法
qq_21201679的博客
04-16 1万+
设图为G=(V,E) 避圈法: 以V上的空图为初始图进行加边操作,依次检查E的边,如果该边加到当前图上不产生圈则将该边加上,否则检查下一条未检查边直至所有边都被检查; 破圈法:以G为初始图进行去边操作,依次检查E的边,如果该边被当前图的某个圈包含则将该边去掉,否则检查下一条未检查边直至所有边都被检查。 通俗来讲:避圈法是:你一直找最短的边然后保留下来,前提是不会形成回路; 破圈法是:看见回路就找那...
python算法图解和题目演示大全.rar
01-09
2. **进阶算法**:可能会涵盖动态规划、贪心算法、回溯法、分支限界法、图论算法(如Dijkstra最短路径算法、Floyd-Warshall所有对最短路径算法Prim最小生成树算法Kruskal最小生成树算法)等。 3. **图形化解释*...
算法图解-python,算法图解python3
09-10
图论部分,书中介绍了最小生成树PrimKruskal算法)和最短路径问题(Dijkstra算法),这些都是网络优化和路由问题中的重要算法。 最后,书中可能还会涵盖动态规划,这是一种解决最优化问题的强大技术,可以...
最小生成树kruskal算法
└┼﹡keep it simple,stupid■┐*…
12-10 109
介绍最小生成树,就是在一个连通无向图中,每条边都有一个权重w,我们可以找到一个无环的,能将所有顶点连接起来的,并且拥有最小权重的树。kruskal算法就是其中一个计算最小生成树算法,这个算法中用到了一个数据结构不相交集合。kruskal算法属于贪婪算法,它的主要思想就是,每次选择一条权重最小的边加入到最小生成树集合中。kruskal算法的形象化实现kruskal实现如下...
python实现prim 最小生成树算法 源码
08-04
python实现prim 最小生成树算法 源码
大话数据结构-普里姆算法Prim)和克鲁斯卡尔算法Kruskal
村长Korbin
03-02 6430
最小生成树的定义,普里姆算法Prim)和克鲁斯卡尔(Kruskal),以及各种存储结构下的最小生成树的代码实现
普里姆Prim最小生成树
09-12 447
#include// 用prim算法构造五项连通图网的最小生成树 #define maxcost 1000 int gm[50][50]; void prim(int tree[],int cost[],int n) {//从序号为0的顶点出发,建立连通网的最小生成树,二
最小生成树---Prim算法Kruskal算法
weixin_52847003的博客
11-25 759
最小生成树算法
最小生成树——Prim算法Kruskal算法
仅以此博客记录日常学习工作中所思所得,水平有限,难登大雅,万望海涵。
07-05 1420
讲解图论中构造最小生成树Prim算法思想,并通过C语言实现算法
最小生成树--Prim算法Kruskal算法
beichengll的博客
08-19 2344
1、最小生成树:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。最小生成树包括三个重要的性质: 最小:边的权重和最小 生成:最小生成树是从原树生成的,包含所有顶点,|v|-1条边都在图里 树:最小生成树还必须是一棵树,无回路,V个顶点一定有|v|-1条边。 最小生成树是连通的,而连通的图一定有一个最小生成树,这是充分必要的。
最小生成树算法Prim 算法Kruskal 算法
xhc6666的博客
03-11 497
难!!!!!有一定基础的看看😭😭
最小生成树算法prim算法kruskal算法
ItsWalter的博客
09-05 782
prim算法又称普利姆算法,目的是在加权连通图中搜索最小生成树。特点是由顶点出发选边,依次选取两个顶点集合之间权值最小的边,两个顶点集合随之变化,最终形成最小生成树。 一个加权连通图,其中顶点集合为V,边集合为E; 标记访问过的顶点集合为Vnew,选取的边集合为Enew,初始化都为空 假设从V中的任一顶点x开始,则Vnew = {x} 重复下列操作,直到Vnew = V。如果顶点有n个,则下面循...
labuladong的算法小抄
08-29
作者在准备面试时,参考了许多算法书籍和在线资源,如《数据结构与算法分析》、《剑指offer》、《啊哈算法》、《图解算法》等,以及浙大的数据结构课程视频。然而,由于时间有限,作者认为labuladong的书最适合他。...
写文章

热门文章

  • 数据结构与算法 —— 最短路径Dijkstra算法(迪杰斯特拉)详细图解以及python实现 15997
  • 数据结构与算法 —— 图的搜索算法(广度/深度优先搜索)以及python实现 4145
  • 数据结构与算法 —— 最小生成树Prim算法和Kruskal算法详细图解以及python实现 3052
  • 数据结构与算法 —— 树的基本操作以及实现(python实现) 2495
  • 数据结构与算法 —— 图 (Graph)的基本介绍 1448

最新评论

  • 数据结构与算法 —— 最小生成树Prim算法和Kruskal算法详细图解以及python实现

    Lavax_II: 请问这个并查集中的并,不加rank有问题吗?不太清楚这个rank的作用,不加貌似不影响最终结果

  • 分而治之--分治算法

    CSDN-Ada助手: 算法 技能树或许可以帮到你:https://edu.csdn.net/skill/algorithm?utm_source=AI_act_algorithm

  • 数据结构与算法 —— 最短路径Dijkstra算法(迪杰斯特拉)详细图解以及python实现

    阿J~: 大佬出品,必属精品~

  • Python打印空心三角和希尔顿序列

    CSDN-Ada助手: 恭喜您写了第7篇博客,内容十分实用,尤其是讲解Python打印空心三角和希尔顿序列。希望您能继续保持创作热情,分享更多有趣的技术经验和心得体会。建议下一步可以尝试分享一些实战经验或者深入剖析某个技术细节,让读者可以更深入地了解相关知识。期待您更多的精彩博客! CSDN 会根据你创作的博客的质量,给予优秀的博主博客红包奖励。请关注 https://bbs.csdn.net/forums/csdnnews?typeId=116148&utm_source=csdn_ai_ada_blog_reply7 看奖励名单。

大家在看

  • 题解:逆序对的计算
  • PopupMenu插件的用法
  • mathtype产品秘钥7.7版本(附激活教程+ 注册激活码) 475
  • camtasia2024最新永久免费破解密钥最新版
  • Tuxera NTFS for Mac破解版下载2024免费苹果电脑磁盘读写工具 540

最新文章

  • 最大流之Ford-Fulkerson和Edmonds-Karp算法
  • 贪心/分治/动态规划 -- 总结
  • 动态规划1(DP)
2024年5篇
2023年6篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

深圳坪山网站建设公司免费网站优化沈阳手机优化网站做网站加优化吗5年网站seo优化费用洪江如何优化网站网站的优化具有云速捷独一怎么给网站做优化湖塘网站优化宝山区官方网站优化网站优化西安六安网站推广优化公司优化网站软件采选火30星棒济南企业网站关键词优化海淀网站快速优化排名常熟市网站关键词优化如何泸州网站优化软件大品牌房产网站快速排名优化方式知名网站优化注意事项龙游网站关键词优化网站关键词优化官方名字潮州网站建设优化公司卢镇seo网站优化排名滨州网站优化建设公司万安网站seo优化焦作seo网站推广优化企业网站优化推广意味着什么博尔塔拉蒙古网站优化南岔县网站seo优化排名胜芳seo网站优化软件知名的网站关键词优化香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

深圳坪山网站建设公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化