本文目录导读:

我来介绍如何使用NetworkX实现欧拉回路的案例。
欧拉回路的基本概念
欧拉回路是经过图中每条边恰好一次,最后回到起点的路径,判断条件:
- 无向图:所有顶点度数均为偶数
- 有向图:每个顶点的入度等于出度
完整案例代码
import networkx as nx
import matplotlib.pyplot as plt
def find_eulerian_circuit():
"""查找并可视化欧拉回路"""
# 方法1:创建满足欧拉回路条件的图
G = nx.Graph()
# 添加边构造一个欧拉图(所有节点度数为偶数)
edges = [
('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'A'), # 四边形
('A', 'C'), ('B', 'D') # 对角线
]
G.add_edges_from(edges)
# 检查图是否存在欧拉回路
print("=== 检查是否满足欧拉回路条件 ===")
print(f"节点数量: {G.number_of_nodes()}")
print(f"边数量: {G.number_of_edges()}")
# 检查连通性
print(f"是否连通: {nx.is_connected(G)}")
# 检查所有节点度数
all_even = all(d % 2 == 0 for node, d in G.degree())
print(f"所有节点度数为偶数: {all_even}")
if all_even and nx.is_connected(G):
print("\n✓ 存在欧拉回路!")
# 查找欧拉回路
euler_circuit = list(nx.eulerian_circuit(G))
print(f"\n欧拉回路路径:")
for i, (u, v) in enumerate(euler_circuit, 1):
print(f"第{i}步: {u} -> {v}")
return G, euler_circuit
else:
print("\n✗ 不存在欧拉回路")
return None, None
def create_eulerian_graph():
"""创建一个确保有欧拉回路的图"""
# 使用更复杂的方式构建
G = nx.Graph()
# 添加节点
nodes = ['1', '2', '3', '4', '5', '6']
G.add_nodes_from(nodes)
# 确保所有节点度数为偶数
edges = [
('1', '2'), ('2', '3'), ('3', '1'), # 三角形1
('4', '5'), ('5', '6'), ('6', '4'), # 三角形2
('2', '5'), ('3', '4'), ('1', '6') # 连接边
]
G.add_edges_from(edges)
return G
def visualize_eulerian_circuit(G, euler_circuit):
"""可视化欧拉回路"""
plt.figure(figsize=(12, 8))
# 设置布局
pos = nx.spring_layout(G, seed=42)
# 绘制图
nx.draw_networkx_nodes(G, pos, node_color='lightblue',
node_size=500, alpha=0.8)
nx.draw_networkx_labels(G, pos, font_size=12, font_weight='bold')
# 先绘制普通边
nx.draw_networkx_edges(G, pos, edge_color='gray',
style='dashed', alpha=0.5)
# 绘制欧拉回路路径(带箭头)
for i, (u, v) in enumerate(euler_circuit):
# 标记路径顺序
plt.annotate(f'{i+1}',
xy=((pos[u][0] + pos[v][0])/2,
(pos[u][1] + pos[v][1])/2),
ha='center', va='center',
bbox=dict(boxstyle='circle', facecolor='yellow',
edgecolor='black'),
fontsize=10, fontweight='bold')
# 绘制路径边
nx.draw_networkx_edges(G, pos, edgelist=[(u, v)],
edge_color='red', width=2)
plt.title("欧拉回路可视化(黄色数字表示路径顺序)", fontsize=14)
plt.axis('off')
plt.tight_layout()
plt.show()
def eulerian_circuit_with_animation(G, euler_circuit):
"""分步显示欧拉回路"""
print("\n=== 欧拉回路分步演示 ===")
pos = nx.spring_layout(G, seed=42)
plt.figure(figsize=(10, 8))
# 绘制基础图
nx.draw_networkx_nodes(G, pos, node_color='lightgreen',
node_size=500, alpha=0.8)
nx.draw_networkx_labels(G, pos, font_size=12, font_weight='bold')
nx.draw_networkx_edges(G, pos, edge_color='gray',
style='dashed', alpha=0.3)
# 分步显示
visited_edges = []
current_node = euler_circuit[0][0]
print(f"起始节点: {current_node}")
for i, (u, v) in enumerate(euler_circuit, 1):
visited_edges.append((u, v))
# 绘制已访问的边
nx.draw_networkx_edges(G, pos, edgelist=visited_edges,
edge_color='red', width=2)
# 标记当前节点
nx.draw_networkx_nodes(G, pos, nodelist=[current_node],
node_color='yellow', node_size=600)
current_node = v
# 添加路径信息
plt.title(f"欧拉回路 - 第{i}步: {u} -> {v}", fontsize=14)
if i == len(euler_circuit):
plt.title(f"欧拉回路完成! 回到起点 {v}", fontsize=14)
plt.axis('off')
plt.pause(0.5)
plt.show()
def practical_example():
"""实际应用案例:邮差送信路线"""
print("\n=== 实际应用:邮差送信路线规划 ===")
# 创建街道网络图
G = nx.Graph()
# 街道交叉口
intersections = ['A', 'B', 'C', 'D', 'E', 'F']
# 街道(确保是欧拉图)
streets = [
('A', 'B', {'street': '主街', 'length': 100}),
('B', 'C', {'street': '东街', 'length': 150}),
('C', 'D', {'street': '南街', 'length': 120}),
('D', 'A', {'street': '西街', 'length': 130}),
('A', 'E', {'street': '中央街', 'length': 80}),
('B', 'F', {'street': '北街', 'length': 90}),
('E', 'F', {'street': '环城路', 'length': 200}),
('C', 'F', {'street': '新区路', 'length': 110}),
('D', 'E', {'street': '老城路', 'length': 95})
]
G.add_edges_from(streets)
# 检查欧拉回路
if all(d % 2 == 0 for n, d in G.degree()):
euler_circuit = list(nx.eulerian_circuit(G))
print("邮差最优路线:")
total_length = 0
for i, (u, v) in enumerate(euler_circuit, 1):
length = G[u][v]['length']
total_length += length
street_name = G[u][v]['street']
print(f"{i}. {u} -> {v} ({street_name},{length}米)")
print(f"\n总路线长度: {total_length}米")
# 可视化
plt.figure(figsize=(10, 8))
pos = nx.spring_layout(G, seed=42, k=2)
# 绘制街道网络
nx.draw_networkx_nodes(G, pos, node_color='lightblue',
node_size=800, alpha=0.8)
nx.draw_networkx_labels(G, pos, font_size=14, font_weight='bold')
# 绘制所有街道
nx.draw_networkx_edges(G, pos, edge_color='gray',
style='dashed', alpha=0.5)
# 绘制欧拉回路
nx.draw_networkx_edges(G, pos, edgelist=euler_circuit,
edge_color='red', width=2.5)
plt.title("邮差最优送信路线(红色:欧拉回路)", fontsize=14)
plt.axis('off')
plt.tight_layout()
plt.show()
# 主程序
if __name__ == "__main__":
print("NetworkX 欧拉回路案例分析")
print("=" * 40)
# 1. 基本欧拉回路
G, circuit = find_eulerian_circuit()
if circuit:
# 2. 可视化
visualize_eulerian_circuit(G, circuit)
# 3. 分步演示
eulerian_circuit_with_animation(G, circuit)
# 4. 构建自定义欧拉图
G2 = create_eulerian_graph()
print(f"\n自定义欧拉图 - 节点数: {G2.number_of_nodes()}, 边数: {G2.number_of_edges()}")
# 5. 实际应用案例
practical_example()
print("\n程序运行完成!")
关键函数说明
nx.eulerian_circuit(G): 查找欧拉回路的核心函数nx.is_connected(G): 检查图的连通性G.degree(): 获取节点度数
判断欧拉回路的条件
def check_eulerian_condition(G):
"""检查欧拉回路条件"""
# 检查连通性
if not nx.is_connected(G):
return False, "图不连通"
# 检查度数
odd_degree_nodes = [n for n, d in G.degree() if d % 2 != 0]
if odd_degree_nodes:
return False, f"奇数度节点: {odd_degree_nodes}"
return True, "存在欧拉回路"
这个案例包含了完整的欧拉回路检测、可视化、分步演示和实际应用,希望对你有帮助!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播