一.Prim算法

算法思想 :

1.将所有得顶点分为两类(U,U-V)初始状态顶点全在U-V中

2.随意从U-V选择一个顶点到U中

3.然后从U 中的顶点开始到U-V中的顶点,找到一个权值最小的边,然后将此边的尾部的顶点加入到U中

4.重复3的操作,直到U-V中的所有顶点移入到U

如图1 开始的时候加入1 到U集合中 此时U={1},U-V={2,3,4,5}

寻找U中顶点连接着的最小权值得顶点也就是1连接着得最小得权值

图二找到一条最小权值得边  1->4 将顶点4加入到U中 此时此时U={1,4},U-V={2,3,5}

然后继续寻找U中顶点连接着得最小得权值,不过此时有U中有两个顶点,

需要找得是两个顶点连接着得最小权值

找到了 1->2 这条边,将顶点2加入到U中,此时U={1,2,4},U-V={3,5}

然后继续重复寻找U中顶点连接着得顶点最小得权值

找到了 2 ->3 ,将顶点3加入到U ,此时U={1,2,3,4},U-V={5}

然后继续寻找最小权值

找到了 1->5,  将顶点5加入到U ,此时U={1,2,3,4,5},U-V={}

最小生成树构造完成

代码展示

例题 : P2820 局域网 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

其中从U向U-V顶点寻找最小权值,借用一个数组来完成

max = 9999
versum, edgesum = map(int, input().split())
edge = [[max for o in range(versum+1)] for i in range(versum+1)]  # 记录w 用0记录数据不连通
ver = [o for o in range(versum+1)]
total_w =0
for i in range(edgesum):a, b, data = map(int, input().split())edge[a][b] = datatotal_w += dataedge[b][a] = data
class node():  # 数组中元素得类型def __init__(self, ver, w):self.ver = verself.w = w
def prim():#u   此为借助得数组,此数组元素表示 ver ->此元素在数组的索引(索引即表示哪一个顶点),以及之间的权值w,如果为0 的话则表示此顶点已加入到U中#默认以1顶点开始进行查找,也可指定其他的#对数组进行初始化,让数组表示从1 到其它顶点的权值,也就是从U->U-Vu = [node(ver[1], edge[1][_]) for _ in range(versum+1)] # _ ==0时无意义,只为了方便索引u[1].w = 0 # 加入到U中s = 0for j in range(versum - 1):  # 寻找足够数量得边maxx = 9999for i in range(1,versum+1):  # 寻找数组在中最小w的值,记录此下标if maxx > u[i].w and u[i].w != 0:  # 0 表示此顶点已加入Umaxx = u[i].wpos = is += u[pos].w #求权值wu[pos].w = 0 #将顶点加入到U#对数组进行更新,以表示新加入顶点,到其他顶点的最小的权值for j in range(1,versum+1):if edge[pos][j] < u[j].w: #新加入的顶点到其他顶点的w,小于原来顶点到其他顶点的值u[j].ver = ver[pos]        #更新u 表示新节点到其他节点的(j)w值u[j].w = edge[pos][j]return s #返回权值记录之和
if __name__  =="main":s = prim()print(total_w - s)

二 Kruskal算法

算法思想 :

将所有边的权值按照从小到大做升序排序,从最小的开始选择,新加入的只要不与原来的边构成环路,就可加入到最小生成树的构件中

其中,如何判断是否能构成环路,则需要借助一个标记数组,此数组用以表示顶点与谁相连,也就是该顶点属于哪个派系 (开始的时候默认为与自己本身相连)借用flag[] 表示

将所有的权值进行升序排序

2->3 1->4 1->2 3->4 1->5 4->5
2 3 5 6 7 8

最小的为 2->3 ,此时查找 2 ,3 的标记不相同,不存在环路,加入 2->3 ,将  3 的标记换成顶点2 的标记, 也就是让 顶点3 加入到顶点1 的派系。

然后选择 1->4 查找 顶点1 顶点4 的标记,不相同, 不构成环路,将 1->4 加入,顶点4 的标记该为顶点一的标记,也就是顶点 4 加入到顶点 1 的派系

选择1->2, 查找1 2 属于哪两个派系也就是查标记,标记不相同,将派系 2 加入到派系1 中,派系2 中的所有成员也跟着加入(再次查询3所属派系时,才会改变为 派系1)

选择最3->4,查找 3 ,4 的派系 ,4 属于派系1 , 其中顶点3 原本属于派系2但是派系2改变为了派系1,所以 3 属于派系1 ,两者派系相同因此舍弃,

然后选择 1->5 ,1 5 所属派系不同,不构成环路 ,5加入派系1 中

选择完成,最小生成树构造完成

  代码实现

例题 P3366 【模板】最小生成树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

  #此代码表示数据的存储 totals_w = 0 #计算所有的权值global edge,Versum,edgesum,flag,rankVersum,edgesum = map(int,input().split())edge = [ list(map(int,input().split())) for _ in range(edgesum)]flag = [i for i in range(Versum+1)] #每一个值都有一个标记

#find 查找用以寻找 该顶点所属的派系

def find(x): #查找顶点与谁连通if flag[x] !=x: flag[x] = find(flag[x]) #路径优化操作,将顶点的派系变为一致return find(flag[x])else:return  x
def kruskal():#寻找最小权重的弧total_w =0 #记录权值ans = 0 #加入边的数量edges = sorted(edge,key = lambda x:x[2]) #对边进行升序排序for i in range(edgesum): x = find(edges[i][0])y = find(edges[i][1])if x !=  y :#返回是否构成回路flag[x] =ytotal_w +=  edges[i][2]ans+=1 if(ans == Versum-1):return total_welse:return "orz"

完整代码 

def find(x):if flag[x] !=x:flag[x] = find(flag[x]) return find(flag[x])else:return  x
def kruskal():#寻找最小权重的弧total_w =0ans = 0edges = sorted(edge,key = lambda x:x[2]) #对弧形进行排序for i in range(edgesum): x = find(edges[i][0])y = find(edges[i][1])if x !=  y :#返回是否构成回路flag[y] =xtotal_w +=  edges[i][2]ans+=1if(ans == Versum-1):return total_welse:return "orz"
def main():totals_w = 0global edge,Versum,edgesum,flag,rankVersum,edgesum = map(int,input().split())edge = [ list(map(int,input().split())) for _ in range(edgesum)]flag = [i for i in range(Versum+1)] #每一个值都有一个标记#rank = [i for i in range(Versum+1)]  #用于确定谁的大小total_w = kruskal()print(total_w)
if __name__ == "__main__":main()

其中find 属于并查集思想,也就是顶点之间连接的所属关系

最小生成树-python实现相关推荐

  1. 最小生成树python算法实践

    为了工作学习中防止忘记,特记下如此笔记,以供查阅. 最近在学图论,涉及到了最小生成树算法. 参考了两篇文章 并集查询 图论最小生成树 原代码复制后格式破坏,特意贴一下我清理后的python代码 # 构 ...

  2. Python小白的数学建模课-A3. 12个新冠疫情数模竞赛赛题与点评

    新冠疫情深刻和全面地影响着社会和生活,已经成为数学建模竞赛的背景帝. 收集了与新冠疫情相关的的数学建模竞赛赛题,关注收藏本文或者在评论区留下邮箱,送你赛题分析点评及优秀论文. 『Python小白的数学 ...

  3. 数据结构之图:加权无向图与寻找最小生成树,Python——27

    加权无向图与prim算法和Kruskal算法寻找最小生成树 加权无向图的介绍 引入 加权无向图是一种为每条边关联一 个权重值或 是成本的图模型.这种图能够自然地表示许多应用.在一副航空图中,边表示航线 ...

  4. Python数模笔记-NetworkX(4)最小生成树

    1.生成树和最小生成树 1.1 生成树 连通的无圈图称为树,就是不包含循环的回路的连通图. 对于无向连通图,生成树(Spanning tree)是原图的极小连通子图,它包含原图中的所有 n 个顶点,并 ...

  5. python机器学习案例系列教程——最小生成树(MST)的Prim算法和Kruskal算法

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 最小生成树MST 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边. ...

  6. python最小生成树算法_图算法|Prim算法求最小生成树

    01 - 一个实际问题 要在n个城市之间铺设光缆,要求有2个: 这 n 个城市的任意两个之间都可以通信: 铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此要使铺设光缆的总费用最低. 如下所示 ...

  7. python【数据结构与算法】最小生成树之Kruskal算法

    我们用现在来模拟一下Kruskal算法,下面给出一个无向图B,我们使用Kruskal来找无向图B的最小生成树. 首先,我们将所有的边都进行从小到大的排序.排序之后根据贪心准则,我们选取最小边(A,D) ...

  8. 【数据结构与算法python】最小生成树算法-Prim算法

    1.引入 本算法涉及到在互联网中网游设计者和网络收音机所面临的问题:信息广播问题,如网游需要让所有玩家获知其他玩家所在的位置,收音机则需要让所有听众获取直播的音频数据 2.算法介绍 (1)单播解法 信 ...

  9. Python 实现Prim最小生成树算法

    最小生成树(MST):对于带权无向图所有的生成树中,代价最小的生成树称为图的最小生成树. Prim算法:假设N=(V,E) 是具有n个顶点的连通图,设U是最小生成树中顶点的集合,设TE是最小生成树中边 ...

最新文章

  1. python切片操作例题_Python之切片操作
  2. DHCP服务器是什么?-Vecloud
  3. c 输出空格_Python编程:案例详解输出函数print
  4. 计算机教育杂志社投稿送样刊,山东教育杂志社投稿期刊论文征稿发表-陶润杂志网...
  5. OpenCV学习(1) OpenCV的安装
  6. Java黑皮书课后题第8章:*8.8(所有最近的点对)修改程序清单8-3,找出所有所有具有最小距离的点对。下面是一个运行示例
  7. http请求协议分析
  8. Java基础_0206:方法的定义与使用
  9. java actionscript_ActionScript(对比Java)学习笔记二
  10. git提交时发现iml文件没有被排除
  11. php html页面获取session,怎么在html中获取session变量
  12. JAVA求数组的平均数,众数,中位数
  13. Scanner初学需要注意的几个问题
  14. 关于Time.deltatTime的理解
  15. Java知识整理5-Java核心 (一)Java IO/NIO
  16. 热烈祝贺高分十三号卫星发射成功
  17. Redis高级之——redis-trib.rb命令详解
  18. 斑马打印机 ZPL打印
  19. 云时代的阡陌纵横”的数据网络?
  20. 7-16 约分最简分式

热门文章

  1. Java高并发秒杀系统【观后总结】
  2. 论文翻译解读:Logmap:Logic-based and scalable ontology matching
  3. linux C/C++ 后端服务问题排查(gdb, pstack,valgrind)
  4. PDF分割与合并(充分利用Spire的bug实现操作PDF)
  5. 用微软Custom Version识别水果:三分钟开发人工智能小应用
  6. 物联网毕设分享 STM32 wifi照明控制系统 - 智能路灯(毕设分享)
  7. php上传文件失败的原因,PHP图片文件上传失败的原因
  8. java通过比对MD5值判断是否是相同图片
  9. 小红书3大新功能上线,提升笔记转化率和品牌投放效果
  10. ELK浅入浅出之环境搭建