news 2026/4/18 20:19:15

别再死记硬背欧拉公式了!用Python可视化平面图,3分钟搞懂n-m+r=2

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
别再死记硬背欧拉公式了!用Python可视化平面图,3分钟搞懂n-m+r=2

用Python可视化平面图:3分钟动态验证欧拉公式

第一次接触欧拉公式时,盯着那个简洁的n-m+r=2看了半天——公式里的字母我都认识,可它们组合起来就像天书。直到某天用Python画出了K5和K3,3的平面嵌入图,突然发现那些抽象的数学符号在屏幕上活了过来。这就像用X光机给数学定理做了次透视,公式背后的几何结构变得一目了然。

1. 平面图的可视化准备

安装好networkx和matplotlib后,我们先从最简单的环形图开始热身。在Jupyter Notebook里运行以下代码,你会看到六个节点均匀分布在圆周上,像钟表刻度般整齐排列:

import networkx as nx import matplotlib.pyplot as plt G = nx.cycle_graph(6) pos = nx.circular_layout(G) # 环形布局 nx.draw(G, pos, with_labels=True, node_color='lightblue') plt.show()

平面图(Planar Graph)的核心特征是边可以在平面上绘制且互不交叉。但有些图天生就拒绝这种优雅——比如著名的K5(五个节点两两相连)和K3,3(二分图各三个节点全连接)。试试用下面的代码生成K5:

K5 = nx.complete_graph(5) pos = nx.spring_layout(K5, seed=42) # 随机布局 nx.draw(K5, pos, with_labels=True, node_color='salmon') plt.show()

你会看到边像纠结的意大利面般缠绕在一起。这就是典型的非平面图特征,也是图论中著名的库拉托夫斯基定理的直观体现。

2. 欧拉公式的动态验证

欧拉公式的魔法在于它将拓扑不变量联系起来。让我们用Python构建一个立方体图来验证:

cube = nx.grid_graph([2,2,2]) # 3D立方体图 pos = nx.spring_layout(cube) nx.draw(cube, pos, with_labels=True) # 计算要素 n = len(cube.nodes) # 节点数=8 m = len(cube.edges) # 边数=12 r = 6 # 通过可视化可数出面数(6个正方形面) print(f"n - m + r = {n} - {m} + {r} = {n - m + r}") # 输出8-12+6=2

更酷的是实时修改图形观察公式变化。删除一条对角线边,面数会如何变化?

cube.remove_edge((0,0,0), (1,1,1)) # 删除空间对角线 r = 5 # 现在外部大面+4个侧面 print(f"修改后: 8 - 11 + 5 = {8 - 11 + 5}") # 依然等于2

3. 极大平面图的特征识别

极大平面图就像充满三角形的网格气球。判断标准很简单:每个面都是三角形(度数为3)。用代码检测四面体图:

tetrahedron = nx.complete_graph(4) pos = nx.planar_layout(tetrahedron) nx.draw(tetrahedron, pos, with_labels=True) # 面度数检测 def is_maximal_planar(G): return all(len(face) == 3 for face in nx.planar_faces(G)) print(f"是否极大平面图: {is_maximal_planar(tetrahedron)}") # 返回True

对比K5删边后的情况:

K5_minus_edge = nx.complete_graph(5) K5_minus_edge.remove_edge(0,1) # 删除任意一条边 print(f"K5删边后是否极大平面: {is_maximal_planar(K5_minus_edge)}") # 仍然False

4. 平面性判定实战技巧

虽然库拉托夫斯基定理给出了理论依据,但实际判断时可以用以下经验法则:

  • 边数阈值:对于n≥3的简单连通图,若m > 3n-6则必定非平面
  • 二分图特例:对于不含3-cycles的图,若m > 2n-4则非平面

用Python快速验证K3,3:

K33 = nx.complete_bipartite_graph(3,3) n, m = len(K33.nodes), len(K33.edges) print(f"3n-6={3*6-6}, 实际边数{m}") # 12>9 print(f"2n-4={2*6-4}, 实际边数{m}") # 9>8

可视化时有个小技巧——使用planar_layout尝试平面排布:

try: pos = nx.planar_layout(K33) # 会抛出NetworkXException except nx.NetworkXException: print("无法生成平面布局,证实是非平面图")

5. 高级可视化技巧

要让面边界更清晰,可以使用面填充技术。以下代码展示如何突出显示平面图的外部面:

from matplotlib.patches import Polygon G = nx.octahedral_graph() # 八面体图 pos = nx.planar_layout(G) nx.draw(G, pos, with_labels=True) # 获取外部面顶点坐标 outer_face = [pos[v] for v in [0,1,2,3,0]] plt.gca().add_patch(Polygon(outer_face, alpha=0.2, color='gold')) plt.show()

对于更复杂的图形,可以结合graphviztwopi布局获得更好的展示效果:

pos = nx.nx_agraph.graphviz_layout(G, prog='twopi', args='-Goverlap=scale') nx.draw(G, pos, node_size=500, alpha=0.8)

记得在代码中适时添加plt.savefig('planar_demo.png', dpi=300)保存高质量图像,方便后续研究或报告使用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 20:15:49

OBS Advanced Timer:6种计时模式让你的直播告别时间焦虑

OBS Advanced Timer:6种计时模式让你的直播告别时间焦虑 【免费下载链接】obs-advanced-timer 项目地址: https://gitcode.com/gh_mirrors/ob/obs-advanced-timer 还在为直播时手忙脚乱看时间而烦恼吗?直播超时、环节混乱、观众流失……这些问题…

作者头像 李华
网站建设 2026/4/18 20:15:09

K8s Pod 卡在 NotReady 状态:深入排查与修复 image filesystem 容量异常

1. 问题现象:集群节点集体罢工 刚用sealos部署完Kubernetes集群,满心欢喜执行kubectl get nodes,结果所有节点清一色显示NotReady状态,就像约好了一起罢工。这种场景下,新手最容易手忙脚乱,老司机则会先喝…

作者头像 李华
网站建设 2026/4/18 20:12:48

原神抽卡记录分析工具:5分钟掌握你的欧非命理

原神抽卡记录分析工具:5分钟掌握你的欧非命理 【免费下载链接】genshin-wish-export Easily export the Genshin Impact wish record. 项目地址: https://gitcode.com/GitHub_Trending/ge/genshin-wish-export 还在为记不住抽了多少发而烦恼吗?每…

作者头像 李华
网站建设 2026/4/18 20:12:47

FanControl终极指南:3步打造你的个性化散热管理系统

FanControl终极指南:3步打造你的个性化散热管理系统 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/F…

作者头像 李华