prim算法求最小生成树

news/2024/7/5 5:49:04

Prim算法是一种求解最小生成树问题的贪心算法,其基本思想是从一个点开始,每次选择离已选取的点集合最近的一个点,添加到集合中,直到所有点都被选取。

以下是Prim算法的基本步骤:

  1. 初始化:选择一个起点作为已选取的点集合,将起点加入到最小生成树中。
  2. 遍历所有边:对于每一条连接已选取的点集合和未选取的点的边,计算边的权值。
  3. 选取边:选择其中权值最小的边,将该边的未选取的点加入到已选取的点集合中,并将该边加入到最小生成树中。
  4. 重复步骤2和3,直到所有点都被选取,算法结束。

在实现Prim算法时,通常采用优先队列来存储边,并使用堆结构来实现。同时,还需要设计一个数据结构来存储已经选取的点和最小生成树中的边。

以下是一个简单的Python实现:

import heapq

def prim(graph):
    n = len(graph)
    visited = [False] * n
    tree = []
    edges = [(i, j, w) for i, j, w in graph]
    heapq.heapify(edges)
    visited[0] = True
    while edges:
        i, j, w = heapq.heappop(edges)
        if not visited[j]:
            visited[j] = True
            tree.append((i, j, w))
            for k, l, v in graph[j]:
                if not visited[l]:
                    heapq.heappush(edges, (j, l, v))
    return tree

其中,graph是一个邻接表,表示无向图。每个元素graph[i]是一个列表,其中每个元素是一个三元组(j, k, w),表示从点i到点j有一条边,权值为wvisited数组用于记录每个点是否已经被选取。tree列表用于存储最小生成树中的边。heapq模块用于实现优先队列。

在上述代码中,我们首先初始化了一个visited数组,用于记录每个点是否已经被选取。然后,我们使用heapq模块将所有的边加入到一个优先队列中,队列中的元素按照边的权值进行排序。

在算法的主循环中,我们从队列中选取权值最小的边,并检查该边的未选取的点是否已经被选取。如果没有,则将该点加入到已选取的点集合中,并将该边加入到最小生成树中。然后,我们遍历该点的所有邻居,并将未选取的邻居加入到优先队列中。

最后,当优先队列为空时,算法结束,我们得到了最小生成树中的所有边。

需要注意的是,在实现Prim算法时,需要保证输入的图是连通的,否则算法将无法得到最小生成树。此外,Prim算法的时间复杂度为O(ElogE),其中E为边的数量。

除了上述基本的Prim算法,还有一些改进的Prim算法,可以在更短的时间内求得最小生成树。

一种改进的方法是使用双向Prim算法。该算法的基本思路是在Prim算法的基础上,从另一个未选取的点开始,再次执行Prim算法,直到所有点都被选取。这种方法可以避免在单向Prim算法中出现的死循环问题,并且可以将算法的时间复杂度降低到O(ElogV),其中V为点的数量。

另一种改进的方法是使用Kruskal算法。该算法的基本思路是将所有的边按照权值从小到大排序,然后依次选择每一条边,如果这条边不会构成环路,则将其加入到最小生成树中。这种方法可以保证每次选取的边都是权值最小的边,直到所有点都被选取。Kruskal算法的时间复杂度为O(ElogE),略高于Prim算法。

在实际应用中,可以根据具体问题的要求和数据的规模来选择合适的算法。如果图的边数较少,可以直接使用Prim算法;如果图的边数较多,可以考虑使用双向Prim算法;如果需要更高的效率,可以使用Kruskal算法。


http://lihuaxi.xjx100.cn/news/1890221.html

相关文章

I.MX RT1170双核学习(2):双核相互激活和启动流程

RT1170这个芯片带有双核:Cortex-M7和Corterx-M4,两个核都可以独立地运行,当然双核也可以同时运行。在上一篇文章中,介绍了一下在RT1170中消息模块MU的使用:双核通信之MU消息单元详解,因为这是双核之间用来通…

群晖(Synology)更换硬盘时间和精神双重折磨的教训

话说玩磁盘阵列的最后结果就是时间上负担不起,并且还被嫌弃。 在磁盘都到位后下一步就是要选择冗余类型了,对大部分人来说使用群晖自己提供的就好了,通常是 SHR。 什么是 SHR Synology Hybrid RAID(SHR)是 Synology…

Nacos配置Mysql数据库

目录 前言1. 配置2. 测试前言 关于Nacos的基本知识可看我之前的文章: Nacos基础版 从入门到精通云服务器 通过docker安装配置Nacos 图文操作以下Nacos的版本为1.1.3 1. 配置 对应的配置文件路径如下: 对应的application.properties为配置文件 需配置端口号 以及 mysql中的…

python自动化测试实战 —— CSDN的Web页面自动化测试

软件测试专栏 感兴趣可看:软件测试专栏 自动化测试学习部分源码 python自动化测试相关知识: 【如何学习Python自动化测试】—— 自动化测试环境搭建 【如何学习python自动化测试】—— 浏览器驱动的安装 以及 如何更…

Java二叉树的遍历

Java二叉树的遍历 大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天,让我们一同探讨Java中二叉树的遍历,解锁这个数据结构的神秘面纱。 J…

【LeetCode每日一题】1904. 你完成的完整对局数

给你两个字符串 startTime 和 finishTime ,均符合 "HH:MM" 格式,分别表示你 进入 和 退出 游戏的确切时间,请计算在整个游戏会话期间,你完成的 完整对局的对局数 。 如果 finishTime 早于 startTime ,这表示…

成功解决 Plugin ‘org.springframework.boot:spring-boot-maven-plugin:‘ not found

Plugin ‘org.springframework.boot:spring-boot-maven-plugin:‘ not found的解决方案,亲测可用! 方法一:清理IDEA的缓存 File -> Invalidate Caches 方法二:添加版本号 先看自己当前的版本号 首先打开pom.xml文件进行查看C…

区块链的可拓展性研究【05】闪电网络

1.闪电网络:闪电网络是一种基于比特币区块链的 Layer2 扩容方案,它通过建立一个双向支付通道网络,实现了快速、低成本的小额支付。闪电网络的交易速度非常快,可以达到每秒数万笔交易,而且交易费用非常低,几…