0

0

Python最小生成树怎么求_Kruskal与Prim算法图论实战

P粉602998670

P粉602998670

发布时间:2026-03-14 14:43:02

|

336人浏览过

|

来源于php中文网

原创

networkx求最小生成树最省事,但需确保图连通、边权为数值且字段名正确;不连通时返回MST森林,非空图;Kruskal手写关键在并查集路径压缩与按秩合并;Prim需惰性删除堆中过期节点。

python最小生成树怎么求_kruskal与prim算法图论实战

Python里用networkx求最小生成树最省事

绝大多数实际场景下,别自己手写KruskalPrim——networkx封装得足够稳,接口直白,还自动处理连通性、权重类型、多重边等边界。

常见错误现象:nx.minimum_spanning_tree(G)返回空图,或报NetworkXError: Graph not connected。这是因为输入图不连通,而MST只对连通图有定义;networkx默认不抛异常,但返回的是原图各连通分量的MST森林(即每个连通块一棵树),容易误以为失败。

  • 确保图连通:先跑nx.is_connected(G),不连通就按需用nx.connected_components(G)拆开处理
  • 边权必须存在且为数值:字段名默认是'weight',若用costdist,得显式传weight='cost'
  • 稀疏图(边数远小于节点数²)优先选algorithm='kruskal';稠密图可试'prim',但实测差异常不明显

示例:

import networkx as nx<br>G = nx.Graph()<br>G.add_weighted_edges_from([(0,1,2), (1,2,3), (0,2,4)])<br>T = nx.minimum_spanning_tree(G, algorithm='kruskal')

Kruskal手动实现的关键不是排序,而是并查集路径压缩

手写Kruskal时,90%的性能坑和逻辑错出在并查集(Union-Find)上:没做路径压缩,find退化成O(n),整体从O(E log E)掉到O(E·n);没按秩合并,树高失控。

立即学习Python免费学习笔记(深入)”;

使用场景:需要定制边筛选逻辑(比如只取weight > 0.5的边),或教学/面试现场白板编码。

  • 边列表必须预先按weight升序排,但别用sorted(edges, key=lambda x: x[2])反复调用——先存好
  • find函数里必须递归更新父节点:parent[x] = find(parent[x]),否则压缩失效
  • 合并时比较秩(rank)而非单纯赋值,避免树退化;初始化rank全为0

简短示意:

def find(x):<br>    if parent[x] != x:<br>        parent[x] = find(parent[x])  # 路径压缩在此<br>    return parent[x]

闪念贝壳
闪念贝壳

闪念贝壳是一款AI 驱动的智能语音笔记,随时随地用语音记录你的每一个想法。

下载

Prim用堆实现时,heapq不能直接删元素,得惰性删除

Python标准库heapq不支持removedecrease_key,所以经典Prim的“更新邻接点权重”操作不能真改堆里元素,否则堆结构崩坏。必须用惰性删除:每次heappop时检查是否已访问过,跳过无效项。

性能影响明显:堆里可能堆积大量过期条目,最坏情况空间O(E),但实践中只要图不极端稀疏,影响可控。

  • 维护一个in_mst布尔数组(非集合!索引访问O(1))标记节点是否已入树
  • 每次从堆取(weight, node)后,先查if in_mst[node]: continue
  • 不要用dictset存当前最小权值——用数组min_weight[node] = weight,更新时直接赋值,堆里只管推新元组

错误写法:heapq.heapreplace(heap, (new_w, node))——这会破坏堆序,因node可能不在堆顶。

边权为负、浮点精度、自环重边这些细节真会影响结果

最小生成树理论上允许负权边(Kruskal/Prim都适用),但networkx默认把负权当异常,除非显式设ignore_nan=False且数据里没NaN;而手写代码若用float('inf')初始化距离,遇到负权可能溢出或逻辑错乱。

真实数据常见坑:

  • 浮点权值(如0.1 + 0.2 != 0.3)导致排序不稳定,sorted()结果不可复现;建议转整型放大(int(w * 100))或用decimal(小规模图)
  • 自环(u == v)和重边(多条u-v边)会被networkx自动忽略或保留最大/最小权那条,取决于multigraph设置;手写时务必先过滤自环
  • 无向图边存两次(u-v, v-u)没问题,但Prim遍历时若没去重,同一节点可能被多次加入堆

最容易被忽略的点:图含孤立节点(度为0)时,MST必须包含它(作为单点树),但很多手写代码初始化时漏掉,导致结果少节点。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

595

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

108

2025.10.23

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

847

2023.08.22

java break和continue
java break和continue

本专题整合了java break和continue的区别相关内容,阅读专题下面的文章了解更多详细内容。

261

2025.10.24

c语言union的用法
c语言union的用法

c语言union的用法是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型,union的使用可以帮助我们节省内存空间,并且可以方便地在不同的数据类型之间进行转换。使用union时需要注意对应的成员是有效的,并且只能同时访问一个成员。本专题为大家提供union相关的文章、下载、课程内容,供大家免费下载体验。

129

2023.09.27

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1051

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

615

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

335

2025.08.29

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 5万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号