news 2026/3/1 0:32:58

Prim 最小生成树算法(MST)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Prim 最小生成树算法(MST)

Prim算法是贪婪算法,类似于Kruskal算法。该算法始终从单个节点出发,经过多个相邻节点,以探索沿途所有连接的边。

该算法从一个空生成树开始。
其理念是维持两组顶点。第一组包含已包含在MST中的顶点,另一组包含尚未包含的顶点。
每一步,它都会考虑连接这两个集合的所有边,并从这些边中选择最小权重边。选定边后,将边的另一端点移动到包含MST的集合。

普里姆算法的工作原理
确定一个任意顶点作为MST的起始顶点。我们在上图中选择0。
按照步骤3到5,直到出现不包含在MST中的顶点(称为边缘顶点)。
找到连接任意树顶点与边缘顶点的边。
在这些边中找出最小值。
将选定的边添加到MST中。由于我们只考虑连接边缘顶点与其余边的边,因此从未得到一个环。
归还MST并离开
邻接矩阵表示的简单实现
按照上述步骤,利用上述Prim算法来求图的MST:

创建一个集合mstSet,跟踪MST中已包含的顶点。
为输入图中的所有顶点分配一个关键值。将所有键值初始化为无限。将第一个顶点的键值指定为0,这样它会被优先选中。
虽然mstSet不包含所有顶点
=> 选择一个mstSet 中不存在且有最小键值的顶点u。
=> 将u包含在mstSet中。
=> 更新 u 所有相邻顶点的键值。要更新键值,遍历所有相邻顶点。对于每个相邻顶点 v,如果边 u-v 的权重小于 v 的前一个键值,则将键值更新为 u-v 的权重。
使用关键值的目的是从切割中选择最小权重边。键值仅用于尚未包含在MST中的顶点,这些顶点的键值表示连接它们与MST中顶点集合的最小权重边。

import java.io.*; import java.lang.*; import java.util.*; class MST { // A utility function to find the vertex with minimum // key value, from the set of vertices not yet included // in MST int minKey(int key[], Boolean mstSet[]) { // Initialize min value int min = Integer.MAX_VALUE, min_index = -1; for (int v = 0; v < mstSet.length; v++) if (mstSet[v] == false && key[v] < min) { min = key[v]; min_index = v; } return min_index; } // A utility function to print the constructed MST // stored in parent[] void printMST(int parent[], int graph[][]) { System.out.println("Edge \tWeight"); for (int i = 1; i < graph.length; i++) System.out.println(parent[i] + " - " + i + "\t" + graph[parent[i]][i]); } // Function to construct and print MST for a graph // represented using adjacency matrix representation void primMST(int graph[][]) { int V = graph.length; // Array to store constructed MST int parent[] = new int[V]; // Key values used to pick minimum weight edge in // cut int key[] = new int[V]; // To represent set of vertices included in MST Boolean mstSet[] = new Boolean[V]; // Initialize all keys as INFINITE for (int i = 0; i < V; i++) { key[i] = Integer.MAX_VALUE; mstSet[i] = false; } // Always include first 1st vertex in MST. // Make key 0 so that this vertex is // picked as first vertex key[0] = 0; // First node is always root of MST parent[0] = -1; // The MST will have V vertices for (int count = 0; count < V - 1; count++) { // Pick the minimum key vertex from the set of // vertices not yet included in MST int u = minKey(key, mstSet); // Add the picked vertex to the MST Set mstSet[u] = true; // Update key value and parent index of the // adjacent vertices of the picked vertex. // Consider only those vertices which are not // yet included in MST for (int v = 0; v < V; v++) // graph[u][v] is non zero only for adjacent // vertices of m mstSet[v] is false for // vertices not yet included in MST Update // the key only if graph[u][v] is smaller // than key[v] if (graph[u][v] != 0 && mstSet[v] == false && graph[u][v] < key[v]) { parent[v] = u; key[v] = graph[u][v]; } } // Print the constructed MST printMST(parent, graph); } public static void main(String[] args) { MST t = new MST(); int graph[][] = new int[][] { { 0, 2, 0, 6, 0 }, { 2, 0, 3, 8, 5 }, { 0, 3, 0, 0, 7 }, { 6, 8, 0, 0, 9 }, { 0, 5, 7, 9, 0 } }; // Print the solution t.primMST(graph); } }

输出
Edge Weight
0 - 1 2
1 - 2 3
0 - 3 6
1 - 4 5
时间复杂度:O(V2由于我们使用邻接矩阵,如果输入图用邻接列表表示,那么借助二元堆,Prim算法的时间复杂度可以简化为O((E+V) * logV)。
辅助空间:O(V)

使用优先队列和邻接列表的高效实现
对于邻接列表表示,我们可以实现 O(((E+V)*log(V)),因为我们可以在 O(V + E) 时间内找到每个顶点的所有相邻,并且在 O(Log V) 时间内通过优先队列获得最小值。

我们使用优先队列(最小堆)来始终选择权重最小的边。
将第一个顶点及其权重推入队列。
当队列不空时,提取最小权重边。
如果顶点未被访问,将其权重加到变量(res)上,并标记为已访问。
将该顶点所有未访问的相邻顶点推入队列。
处理完所有顶点后,返回以 res(分辨率)存储的总权重。

import java.util.PriorityQueue; import java.util.ArrayList; class GFG { // Returns total weight of the Minimum Spanning Tree static int spanningTree(int V, ArrayList<ArrayList<int[]>> adj) { // Min-heap storing {weight, vertex} PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]); boolean[] visited = new boolean[V]; int res = 0; // Start from node 0 pq.add(new int[]{0, 0}); while(!pq.isEmpty()) { int[] p = pq.poll(); int wt = p[0]; int u = p[1]; if(visited[u]) continue; res += wt; visited[u] = true; // Push adjacent edges for(int[] v : adj.get(u)) { if(!visited[v[0]]) { pq.add(new int[]{v[1], v[0]}); } } } return res; } public static void main(String[] args) { int V = 3; ArrayList<ArrayList<int[]>> adj = new ArrayList<>(); for(int i = 0; i < V; i++) adj.add(new ArrayList<>()); adj.get(0).add(new int[]{1, 5}); adj.get(1).add(new int[]{0, 5}); adj.get(1).add(new int[]{2, 3}); adj.get(2).add(new int[]{1, 3}); adj.get(0).add(new int[]{2, 1}); adj.get(2).add(new int[]{0, 1}); System.out.println(spanningTree(V, adj)); } }

输出
4
时间复杂度:O(((E+V)*log(V)),其中V是顶点数,E是边数。
辅助空间:O(E+V),其中V是顶点数,E是边数

它是如何运作的?
核心基于MST的一个基本性质,称为割性质(如果我们将顶点划分为两组(即割),那么穿越该割的最轻边必须是图中某个MST的一部分。由于我们总是考虑割顶点,因此从不形成循环。

Prim算法的优缺点
优势:

Prim算法保证能在连通加权图中找到MST。
使用二元堆或斐波那契堆时,其时间复杂度为 O((E+V)×log(V)),其中 E 是边数,V 是顶点数。
与其他一些MST算法相比,它是一个相对简单易懂和实现的算法。
缺点:

与Kruskal算法类似,Prim算法在多边密集图上可能较慢,因为它需要至少遍历所有边一次。
Prim算法依赖优先级队列,这会占用额外内存,并在非常大的图中使算法变慢。
起始节点的选择会影响MST输出,这在某些应用中可能并不理想。

编程资源 https://pan.quark.cn/s/7f7c83756948 更多资源 https://pan.quark.cn/s/bda57957c548
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/26 7:35:34

语言模型推理能力的认知风格影响因素分析

语言模型推理能力的认知风格影响因素分析 关键词:语言模型、推理能力、认知风格、影响因素、分析 摘要:本文聚焦于语言模型推理能力的认知风格影响因素进行深入分析。首先介绍了研究的背景、目的、预期读者和文档结构等内容。接着阐述了语言模型、推理能力和认知风格的核心概…

作者头像 李华
网站建设 2026/2/24 11:05:12

有没有推荐的汽车自动化生产系统或智能解决方案?

在汽车制造这个行当里&#xff0c;自动化正在悄悄经历一场本质的蜕变。早年间&#xff0c;我们谈论的还只是机械臂按固定程序焊接、喷涂、搬运——机器固然高效&#xff0c;但说到底&#xff0c;只是听令行事的“工具”。而如今&#xff0c;情况不一样了。随着AI、物联网和数字…

作者头像 李华
网站建设 2026/2/24 12:18:52

AI法律文书准确性测试方法论

一、风险背景与技术挑战 当前法律AI工具在生成起诉状、合同等文书时存在三类核心风险&#xff1a;虚构法条&#xff08;如评测中出现的错误法条引用&#xff09;、逻辑矛盾&#xff08;如将"双方约定"误用为"甲方必须"的强制性表述&#xff09;及过时条款…

作者头像 李华
网站建设 2026/2/23 0:11:31

跨境电商“防关联”实战指南:把风险挡在账号之外

跨境平台的风控越来越“聪明”&#xff1a;同一批设备、网络、支付、收货、资料、操作习惯之间&#xff0c;只要出现可被平台归因的“共同点”&#xff0c;就可能触发关联审查&#xff0c;轻则限流、二审&#xff0c;重则直接封号、资金冻结。防关联不是“玄学”&#xff0c;核…

作者头像 李华
网站建设 2026/2/25 9:27:17

计算机毕业设计springboot基于web的流浪动物信息管理系统 基于SpringBoot的流浪宠物救助与领养平台 Web端流浪猫狗信息追踪及领养服务系统

计算机毕业设计springboot基于web的流浪动物信息管理系统285i7752 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。当城市化的脚步越来越快&#xff0c;街巷里出现的流浪动物也在…

作者头像 李华
网站建设 2026/2/22 1:08:29

孤能子视角:“1+1=2“

我的问题(前两个千问回答&#xff0c;第三个信兄回答):1.看看"112"人类认知演化。2.演化中都遇到哪些困难&#xff0c;最后又如何解决&#xff1f;3.以上是千问对"112"人类认知演化史的解读。EIS又会给出怎样的洞察呢&#xff0c;又会如何判断人工智能学习…

作者头像 李华