连通且不含圈的无向图称为树(tree)。树中度为1的节点称为树叶,度大于1的节点称为分支点。
若图G=(V,E)的生成子图是一棵树,则称该树为图G的生成树(spanning tree),也称支撑树,简称为图G的树。图G中属于生成树的边称为树枝(branch)。
连通图G=(V,E),每条边上有非负权L(e)。一棵树上所有树枝上权的总和,称为这个生成树的权。具有最小权的生成树称为最小生成树(minimum spanning tree),也称最小支撑树,简称最小树。
许多网络问题都可以归结为最小树问题,例如:交通系统,通信系统,局域网系统等等。
最小生成树的算法:

1 普里姆算法(prim算法)

普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现;并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。
给定连通赋权图G=(V,E,W),其中W为邻接矩阵,构造它的最小生成树。设置两个集合P和Q,其中P用于存放G的最小生成树的节点,集合Q存放G的最小生成树的边。令集合P的初值为P={V1}(假设构造最小生成树时从节点V1出发),集合Q的初值Q=空集。Prim算法的思想是,从所有p属于P,v属于V-P的边中,选取具有最小权值得边pv,将节点v加入集合P中,将边pv加入集合Q中,如此不断的重复,直到P=V时,最小生成树构造完毕,这时集合Q包含了最小生成树的所有边。

1 算法简单描述

1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:P = {x},其中x为集合V中的任一节点(起始点),Q = {},为空;
3).重复下列操作,直到P = V:
a.在集合E中选取权值最小的边

2 算法的图例描述

3 简单证明prim算法

反证法:假设prim生成的不是最小生成树

  • 1).设prim生成的树为G0
  • 2).假设存在Gmin使得cost(Gmin)

4 prim算法的python实现

'''
#file:py_prim.py
#最小生成树 prim算法的python实现
'''
debug = 0
MAX_NUM = 10000
v_num = 6grapharr = [[0, 6, 1, 5, MAX_NUM, MAX_NUM],[6, 0, 5, MAX_NUM, 3, MAX_NUM],[1, 5, 0, 5, 5, 4],[5, MAX_NUM, 5, 0, MAX_NUM, 2],[MAX_NUM, 3, 6, MAX_NUM, 0, 6],[MAX_NUM, MAX_NUM, 4, 2, 6, 0],]######################################
# U放已经匹配好的顶点:
U = []
# V初始化为所有顶点的集合:
V = []
# T放各个边:
T = []def init():if (debug):print("grapharr=", end="")print(grapharr)i = 0while i < v_num:V.append(i + 1)i = i + 1def prim_start_vertex(start):if (start < 1):print("ERROR:start=", start)print("ERROR:change start to 1 by default!")start = 1U.append(start)del V[start - 1]def list_sort(l):if (len(l) < 1):print("ERROR:len of l =", len(l))exitindex = 0i = 0min_val = l[0]while i < len(l):if min_val > l[i]:min_val = l[i]index = ii = i + 1if (debug):print("[list_sort]:l=", l, ";index=", index)return indexdef min_wui():m = MAX_NUMclose_edge = {'u': -1, 'v': -1}edge_list = []vertex_list = []i = 0j = 0# 算出U和V之间所有边的长度:lu = len(U)lv = len(V)if (debug):print("##############entry min_wui###########")print("lu=", lu, ";lv=", lv)while i < len(U):while j < len(V):if (debug):print("i=", i, ";j=", j)print("U[i]=", U[i], ";V[j]=", V[j])temp = grapharr[U[i] - 1][V[j] - 1]if (temp > 0):if (temp < MAX_NUM):close_edge = {'u': U[i], 'v': V[j]}if (debug):print("close_edge=", close_edge)vertex_list.append(close_edge)edge_list.append(temp)j = j + 1# for i:i = i + 1j = 0# end of :for while iif (debug):print("vertex_list=", vertex_list)print("edge_list=", edge_list)min_index = list_sort(edge_list)close_edge = vertex_list[min_index]U.append(close_edge['v'])del V[V.index(close_edge['v'])]if (debug):print("U=", U)print("V=", V)return close_edgedef py_prim(start):init()prim_start_vertex(start)print("init values:")print("U=", U)print("V=", V)print("T=", T)while (len(U) != v_num):if (debug):print("len(U)=", len(U))our_edge = min_wui()T.append(our_edge)print("========RESULT============")print("U=", U)print("V=", V)print("T=", T)######################################
if (__name__ == "__main__"):# 开始主程序:debug = 0py_prim(1)调试结果:
init values:
U= [1]
V= [2, 3, 4, 5, 6]
T= []
========RESULT============
U= [1, 3, 6, 4, 2, 5]
V= []
T= [{'v': 3, 'u': 1}, {'v': 6, 'u': 3}, {'v': 4, 'u': 6}, {'v': 2, 'u': 3}, {'v': 5, 'u': 2}]

二 kruskal算法

Kruskal算法是一种用来寻找最小生成树的算法,由Joseph Kruskal在1956年发表。用来解决同样问题的还有Prim算法和Boruvka算法等。三种算法都是贪婪算法的应用。和Boruvka算法不同的地方是,Kruskal算法在图中存在相同权值的边时也有效。

1 kruskal算法的精髓在于:每次选取一条边,该边同时满足:

1、在当前未选边中权值最小;
2、与已选边不构成回路。直到选取n-1条表是算法结束。找到MST活判断不存在MST。

2.算法简单描述

1).记Graph中有v个顶点,e个边
2).新建图Graphnew,Graphnew中拥有原图中相同的e个顶点,但没有边
3).将原图Graph中所有e个边按权值从小到大排序
4).循环:从权值最小的边开始遍历每条边 直至图Graph中所有的节点都在同一个连通分量中
if 这条边连接的两个节点于图Graphnew中不在同一个连通分量中
添加这条边到图Graphnew中

3 图片描述

3.简单证明Kruskal算法
对图的顶点数n做归纳,证明Kruskal算法对任意n阶图适用。
归纳基础:
n=1,显然能够找到最小生成树。
归纳过程:
假设Kruskal算法对n≤k阶图适用,那么,在k+1阶图G中,我们把最短边的两个端点a和b做一个合并操作,即把u与v合为一个点v’,把原来接在u和v的边都接到v’上去,这样就能够得到一个k阶图G’(u,v的合并是k+1少一条边),G’最小生成树T’可以用Kruskal算法得到。
我们证明T’+{

4.代码算法实现

from pylab import *INFINITY = 65535                        #代表无穷大
vexs = array([[0,10,INFINITY,INFINITY,INFINITY,11,INFINITY,INFINITY,INFINITY],#邻接矩阵[10,0,18,INFINITY,INFINITY,INFINITY,16,INFINITY,12],[INFINITY,18,0,22,INFINITY,INFINITY,INFINITY,INFINITY,8],[INFINITY,INFINITY,22,0,20,INFINITY,INFINITY,16,21],[INFINITY,INFINITY,INFINITY,20,0,26,INFINITY,7,INFINITY],[11,INFINITY,INFINITY,INFINITY,26,0,17,INFINITY,INFINITY],[INFINITY,16,INFINITY,24,INFINITY,17,0,19,INFINITY],[INFINITY,INFINITY,INFINITY,16,7,INFINITY,19,0,INFINITY],[INFINITY,12,8,21,INFINITY,INFINITY,INFINITY,INFINITY,0]])lengthVex = len(vexs)                   #邻接矩阵大小
beginEdge = []
endEdge = []
weight = []
group = []
for i in arange(lengthVex):             #生成边集数组group.append([i])for j in arange(i+1,lengthVex):if(vexs[i, j]>0 and vexs[i, j]<INFINITY):beginEdge.append(i)         #每条边的起点endEdge.append(j)           #每条边的终点weight.append(vexs[i, j])   #每条边的权值lengthEdge = len(weight)                #边的条数
sum = 0
for i in arange(lengthEdge):            #遍历每条边I = (argsort(weight))[0]for j in arange(lengthVex):if(beginEdge[I]) in group[j]:m = jif(endEdge[I]) in group[j]:n = jif m != n:                          #判断当前这条边是否属于不同的连通分量,如果是,将其合并group[m] = group[m] + group[n]group[n] = []sum = sum + weight[I]print(weight[I])del weight[I]                       #删除遍历过的边以及顶点del beginEdge[I]del endEdge[I]
print("The length of the minimum cost spanning tree is: ",sum)

5 时间复杂度:elog2e e为图中的边数

复杂网络(2)--图论的基本理论-最小生成树问题相关推荐

  1. prim求最短路径C语言,[图论]Prim算法求最小支撑树和最短路径

    这个是以前所学,现在总结成博文一篇. 对于图论中的求解最小支撑树问题和最短路径问题都有比较经典的算法,比如最小支撑树可以采用"破圈法",求解最短路径可以用"Dijkstr ...

  2. 数学建模之图论——图与网络模型(二)(最小生成树问题、最大流问题)

    建议先看上一篇基本概念篇 https://blog.csdn.net/weixin_45755332/article/details/106899147 最小生成树 基本概念和方法 树:没有圈的连通图 ...

  3. Python小白的数学建模课-18.最小生成树问题

    Python小白的数学建模课-18.最小生成树问题 最小生成树(MST)是图论中的基本问题,具有广泛的实际应用,在数学建模中也经常出现. 路线设计.道路规划.官网布局.公交路线.网络设计,都可以转化为 ...

  4. 数据结构|最小生成树问题

    最小生成树问题 一.需求分析 问题描述:在n个城市间建设信网络,只需要架设n-1条线路即可.以最低的代价建设这个通信网,即求图的最小生成树. 基本功能:程序运用普利姆算法或克鲁斯卡尔算法求网的最小生成 ...

  5. 数据结构与算法-Prim算法解析与解决修路最小生成树问题

    文章目录 简介 Prim算法 最小生成树 应用场景 问题描述 思路分析 代码实现 简介 Prim算法 ​ 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索 ...

  6. 最小生成树问题的算法笔记

    最小生成树问题 前提 在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集且为无循环图,使得 ...

  7. 使用贪心算法解决最小生成树问题。

    使用贪心算法解决最小生成树问题. #include<iostream> #include<algorithm> using namespace std; const int M ...

  8. 实验1 最小生成树问题【Kruskal+Prim】

    1.贪心算法思想 贪心算法的基本思想是找出整体当中每个小的局部的最优解,并且将所有的这些局部最优解合起来形成整体上的一个最优解.因此能够使用贪心算法的问题必须满足下面的两个性质: 1.整体的最优解可以 ...

  9. 【算法】Kruskal算法(解决最小生成树问题) 含代码实现

    Kruskal算法和Prim算法一样,都是求最小生成树问题的流行算法. 算法思想: Kruskal算法按照边的权值的顺序从小到大查看一遍,如果不产生圈或者重边,就把当前这条边加入到生成树中. 算法的正 ...

最新文章

  1. python 遍历字符串的每一个字符_Python之字符串的遍历的4种方式
  2. arcgis 中label feature太长换行_MapGIS转换为ArcGIS小结
  3. python基础教程教材-最好的Python入门教材是哪本?
  4. logback无法生成日志文件之谜
  5. 音视频技术开发周刊 81期
  6. 【CodeForces - 255B】Code Parsing(思维,字符串)
  7. 配置文件存int类型_Redis详解(五)------ redis的五大数据类型实现原理
  8. Spring Boot Shiro权限管理--自定义 FormAuthenticationFilter验证码整合
  9. [导入]CommunityServer 1.1 源码及汉化文件
  10. 02 Python元组 字典 数据类型 if while for 迭代
  11. Android objdump/nm/readelf使用
  12. php ddl,MySQL定义语言[DDL]
  13. 计算机考研408每日一题 day19
  14. win7查找计算机图片,win7系统全盘搜索图片的操作方法
  15. 一个画布有多个子图_如何把多张图拼成一张长图
  16. 三大主流芯片架构特点
  17. 【IC4】运算放大器的开环增益,开环输出电压
  18. Client-Initiated场景下的L2TP实验配置
  19. 三维坐标要建一个4*4的矩阵?
  20. 混沌工程落地的六个阶段

热门文章

  1. android播放器如何获取音乐文件信息
  2. 通过代理使用远程桌面(Mstcs)
  3. 最新无加密好梦防红系统源码
  4. [家里蹲大学数学杂志]第057期图像复原中的改进 TV 模型
  5. 下载文件时火狐总是提示“已屏蔽:可能含有病毒或间谍软件”
  6. 图片的基本读取和保存操作
  7. 如何删除ie9中的bing搜索引擎
  8. 李宇春留长发纯美造型现身网络(组图)
  9. matlab经典music,基于经典music的doa估计matlab仿真.doc
  10. android root 卸载app,如何免ROOT卸载安卓系统自带APP