最小生成树,普里姆算法(Python实现)

December 16, 2015 12:01 PM

1.相关概念

1)生成树 一个连通图的生成树是它的极小连通子图,在n个顶点的情形下,有n-1条边。生成树是对连通图而言的,是连同图的极小连通子图,包含图中的所有顶点,有且仅有n-1条边。非连通图的生成树则组成一个生成森林;若图中有n个顶点,m个连通分量,则生成森林中有n-m条边。

2)和树的遍历相似,若从图中某顶点出发访遍图中每个顶点,且每个顶点仅访问一次,此过程称为图的遍历, (Traversing Graph)。图的遍历算法是求解图的连通性问题、拓扑排序和求关键路径等算法的基础。图的遍历顺序有两种:深度优先搜索(DFS)和广度优先搜索(BFS)。对每种搜索顺序,访问各顶点的顺序也不是唯一的。

3)在一个无向连通图G中,其所有顶点和遍历该图经过的所有边所构成的子图G′ 称做图G的生成树。一个图可以有多个生成树,从不同的顶点出发,采用不同的遍历顺序,遍历时所经过的边也就不同。

在图论中,常常将树定义为一个无回路连通图。对于一个带权的无向连通图,其每个生成树所有边上的权值之和可能不同,我们把所有边上权值之和最小的生成树称为图的最小生成树。求图的最小生成树有很多实际应用。例如,通讯线路铺设造价最优问题就是一个最小生成树问题。
常见的求最小生成树的方法有两种:克鲁斯卡尔(Kruskal)算法和普里姆(Prim)算法。

2.普里姆(Prim)算法

1) 算法的基本思想:

普里姆算法的基本思想:普里姆算法是另一种构造最小生成树的算法,它是按逐个将顶点连通的方式来构造最小生成树的。

从连通网络 N = { V, E }中的某一顶点 u0 出发,选择与它关联的具有最小权值的边(u0, v),将其顶点加入到生成树的顶点集合U中。以后每一步从一个顶点在U中,而另一个顶点不在U中的各条边中选择权值最小的边(u, v),把该边加入到生成树的边集TE中,把它的顶点加入到集合U中。如此重复执行,直到网络中的所有顶点都加入到生成树顶点集合U中为止。

假设G=(V,E)是一个具有n个顶点的带权无向连通图,T(U,TE)是G的最小生成树,其中U是T的顶点集,TE是T的边集,则构造G的最小生成树T的步骤如下:

(1)初始状态,TE为空,U={v0},v0∈V;

(2)在所有u∈U,v∈V-U的边(u,v) ∈E中找一条代价最小的边(u′,v′)并入TE,同时将v′并入U;

重复执行步骤(2)n-1次,直到U=V为止。

在普里姆算法中,为了便于在集合U和(V-U)之间选取权值最小的边,需要设置两个辅助数组closest和lowcost,分别用于存放顶点的序号和边的权值。
对于每一个顶点v

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
普里算法是一种用于构建最小生成的贪心算法。它从一个源节点开始,逐步扩展生成,直到覆盖所有节点。具体步骤如下: 1. 选择一个起始节点,并将其加入生成中。 2. 找到与生成相邻的所有边,并选择其中权重最小的边所连接的节点。 3. 将该节点加入生成中,并将该边加入生成的边集中。 4. 重复步骤2和3,直到生成包含所有节点。 下面是一个使用Python实现普里算法的例子: ```python def prim(graph): # 选择一个起始节点 start_node = list(graph.keys())[0] # 初始化生成和已访问节点集合 visited = set([start_node]) mst = [] # 当已访问节点集合不包含所有节点时 while len(visited) < len(graph): # 找到与生成相邻的所有边 edges = [] for node in visited: for neighbor, weight in graph[node].items(): if neighbor not in visited: edges.append((node, neighbor, weight)) # 选择权重最小的边所连接的节点 min_edge = min(edges, key=lambda x: x[2]) # 将该节点加入生成中,并将该边加入生成的边集中 mst.append(min_edge) visited.add(min_edge[1]) return mst ``` 其中,`graph`是一个字典,表示无向图的邻接表。例如,对于以下无向图: ``` 2 - 3 / / \ 1 - 4 - 5 ``` 可以表示为: ```python graph = { 1: {2: 1, 4: 3}, 2: {1: 1, 3: 1, 4: 2}, 3: {2: 1, 4: 2, 5: 1}, 4: {1: 3, 2: 2, 3: 2, 5: 1}, 5: {3: 1, 4: 1} } ``` 调用`prim(graph)`函数即可得到该图的最小生成
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值