目录

1. 最短路径问题 - 绘制城市间旅行最短路径图

题目描述:

要求:

示例数据:

python 代码实现

实现思想:

要点:

2. 最小生成树问题 - Kruskal算法绘制MST

题目描述:

要求:

示例数据:

python代码实现

实现思想:

要点:

3. 结合最短路径与最小生成树的复杂网络分析

题目描述:

python代码

实现思想: 

要点:

总结三个问题


【数学建模】——【python】实现【最短路径】【最小生成树】【复杂网络分析】-LMLPHP

【数学建模】——【python】实现【最短路径】【最小生成树】【复杂网络分析】-LMLPHP

1. 最短路径问题 - 绘制城市间旅行最短路径图

题目描述:

假设有一个包含多个城市及其之间距离的列表(或图结构),其中每个城市是图中的一个节点,城市之间的距离是边的权重。使用Dijkstra算法或Floyd-Warshall算法(视情况而定,如果图中节点数较多,推荐使用Dijkstra;如果需要求出所有点对间的最短路径,则使用Floyd-Warshall)来计算并绘制出从一个指定城市到其他所有城市的最短路径图。

要求:

示例数据:

python 代码实现

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.font_manager as fm

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 输入城市数量
N = int(input("请输入城市数量: "))

# 生成随机的距离矩阵,距离在1到20之间
distances = np.random.randint(1, 21, size=(N, N))
np.fill_diagonal(distances, 0)  # 对角线距离为0

# 打印生成的距离矩阵
print("城市间的距离矩阵:")
print(distances)

# 创建图并添加边
G = nx.Graph()

# 添加节点
cities = [chr(i) for i in range(65, 65 + N)]  # 使用A, B, C...表示城市
G.add_nodes_from(cities)

# 添加边及其权重
for i in range(N):
    for j in range(i + 1, N):
        G.add_edge(cities[i], cities[j], weight=distances[i][j])

# 输入起始城市
start_city = input(f"请输入起始城市({', '.join(cities)}): ")

# 使用Dijkstra算法计算从起始城市到所有其他城市的最短路径
lengths, paths = nx.single_source_dijkstra(G, source=start_city)

# 打印最短路径信息
print("从起始城市到其他城市的最短路径:")
for target in cities:
    print(f"{start_city}到{target}的最短路径为{paths[target]},距离为{lengths[target]}")

# 获取从起始城市到最后一个城市的最短路径
end_city = cities[-1]
shortest_path = paths[end_city]

# 绘制图形
pos = nx.spring_layout(G)

# 创建绘图区域
fig, ax = plt.subplots()

# 绘制所有节点
nx.draw_networkx_nodes(G, pos, node_size=500, ax=ax)

# 绘制所有边并根据权重调整颜色和宽度
edges = G.edges(data=True)
edge_colors = [edge[2]['weight'] for edge in edges]
edge_widths = [edge[2]['weight'] / 5 for edge in edges]
edges_drawn = nx.draw_networkx_edges(G, pos, edgelist=edges, width=edge_widths, edge_color=edge_colors, edge_cmap=plt.cm.Blues, ax=ax)

# 绘制最短路径的边,使用不同颜色和宽度
path_edges = [(shortest_path[i], shortest_path[i + 1]) for i in range(len(shortest_path) - 1)]
nx.draw_networkx_edges(G, pos, edgelist=path_edges, width=2, edge_color='r', ax=ax)

# 绘制节点标签
nx.draw_networkx_labels(G, pos, font_size=12, font_color='black', ax=ax)

# 绘制边标签
edge_labels = {(edge[0], edge[1]): edge[2]['weight'] for edge in edges}
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, ax=ax)

# 创建颜色映射条
sm = plt.cm.ScalarMappable(cmap=plt.cm.Blues, norm=plt.Normalize(vmin=min(edge_colors), vmax=max(edge_colors)))
sm.set_array([])  # 仅用于显示色条
fig.colorbar(sm, ax=ax, label='距离')

# 显示图形
plt.title(f"从城市 {start_city} 到城市 {end_city} 的最短路径图")
plt.axis('off')
plt.show()

【数学建模】——【python】实现【最短路径】【最小生成树】【复杂网络分析】-LMLPHP

实现思想:

要点:

2. 最小生成树问题 - Kruskal算法绘制MST

题目描述:

给定一个无向带权图,使用Kruskal算法找到并绘制该图的最小生成树(MST)。最小生成树是图中的一个子图,它包含图中所有顶点且边的权重之和最小。

要求:

示例数据:

python代码实现

import networkx as nx
import matplotlib.pyplot as plt

# 边列表,每个元素是一个三元组(起点 终点 权重)
edges = [
    ('A', 'B', 1),
    ('A', 'C', 4),
    ('A', 'D', 7),
    ('B', 'C', 2),
    ('B', 'D', 5),
    ('C', 'D', 3),
    ('C', 'E', 6),
    ('D', 'E', 8)
]

# 构建图
G = nx.Graph()
G.add_weighted_edges_from(edges)

# 使用Kruskal算法计算MST
mst = nx.minimum_spanning_tree(G, algorithm='kruskal')

# 绘制图
pos = nx.spring_layout(G)
plt.figure(figsize=(10, 8))

# 绘制原始图
nx.draw(G, pos, with_labels=True, node_size=500, node_color="lightblue", alpha=0.6)
labels = nx.get_edge_attributes(G, 'weight')
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)

# 绘制MST
nx.draw(mst, pos, with_labels=True, node_size=500, node_color="lightgreen", edge_color="red", width=2)
labels_mst = nx.get_edge_attributes(mst, 'weight')
nx.draw_networkx_edge_labels(mst, pos, edge_labels=labels_mst)

# 计算MST的总权重
total_weight = mst.size(weight='weight')
plt.title(f"Minimum Spanning Tree (Total Weight: {total_weight})")
plt.show()

【数学建模】——【python】实现【最短路径】【最小生成树】【复杂网络分析】-LMLPHP

实现思想:

要点:

3. 结合最短路径与最小生成树的复杂网络分析

题目描述:

考虑一个大型交通网络,其中节点代表城市,边代表道路,边的权重代表道路的长度或旅行时间。首先,使用Kruskal算法找出这个网络的最小生成树(代表最基本的交通网络框架)。然后,在此MST的基础上,选择一个“核心城市”作为起点,使用Dijkstra算法找出从该城市到其他所有城市的最短路径。

要求:

示例数据:

python代码

import networkx as nx
import matplotlib.pyplot as plt
from matplotlib import font_manager

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决坐标轴负号显示问题

# 边列表,每个元素是一个三元组(起点, 终点, 权重)
edges = [
    ('A', 'B', 1),
    ('A', 'C', 4),
    ('A', 'D', 7),
    ('B', 'C', 2),
    ('B', 'D', 5),
    ('C', 'D', 3),
    ('C', 'E', 6),
    ('D', 'E', 8)
]

# 构建图
G = nx.Graph()
G.add_weighted_edges_from(edges)

# 使用Kruskal算法计算MST
mst = nx.minimum_spanning_tree(G, algorithm='kruskal')

# 使用Dijkstra算法计算最短路径
core_city = 'A'
lengths, paths = nx.single_source_dijkstra(mst, source=core_city)

# 绘制MST
pos = nx.spring_layout(G)
plt.figure(figsize=(20, 8))

plt.subplot(121)
nx.draw(G, pos, with_labels=True, node_size=500, node_color="lightblue", alpha=0.6)
labels = nx.get_edge_attributes(G, 'weight')
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)

nx.draw(mst, pos, with_labels=True, node_size=500, node_color="lightgreen", edge_color="red", width=2)
labels_mst = nx.get_edge_attributes(mst, 'weight')
nx.draw_networkx_edge_labels(mst, pos, edge_labels=labels_mst)
total_weight = mst.size(weight='weight')
plt.title(f"最小生成树 (总权重: {total_weight})")

# 绘制最短路径图
plt.subplot(122)
nx.draw(mst, pos, with_labels=True, node_size=500, node_color="lightblue")
labels_mst = nx.get_edge_attributes(mst, 'weight')
nx.draw_networkx_edge_labels(mst, pos, edge_labels=labels_mst)

for target in lengths:
    if target == core_city:
        continue
    path = paths[target]
    edges_in_path = [(path[i], path[i + 1]) for i in range(len(path) - 1)]
    nx.draw_networkx_edges(mst, pos, edgelist=edges_in_path, width=2, edge_color='r')
    path_length = lengths[target]
    plt.text(pos[path[-1]][0], pos[path[-1]][1], f"{path_length:.2f}", fontsize=12, color='red')

plt.title(f"从核心城市 {core_city} 出发的最短路径")

plt.show()

【数学建模】——【python】实现【最短路径】【最小生成树】【复杂网络分析】-LMLPHP

实现思想: 

要点:

总结三个问题

【数学建模】——【python】实现【最短路径】【最小生成树】【复杂网络分析】-LMLPHP

这三个问题分别涉及图论中的最短路径问题、最小生成树问题以及结合这两种方法的复杂网络分析。第一个问题使用Dijkstra算法计算并可视化了从一个指定城市到其他所有城市的最短路径,第二个问题使用Kruskal算法找到并绘制了一个无向带权图的最小生成树,第三个问题在最小生成树的基础上,使用Dijkstra算法计算并展示了从核心城市到其他所有城市的最短路径。每个问题都结合了图的构建、算法的应用和结果的可视化。

07-25 11:40