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

news2025/4/20 4:38:10

目录

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

题目描述:

要求:

示例数据:

python 代码实现

实现思想:

要点:

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

题目描述:

要求:

示例数据:

python代码实现

实现思想:

要点:

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

题目描述:

python代码

实现思想: 

要点:

总结三个问题


ce6fbd68767d465bbe94b775b8b811db.png

731bd47804784fa2897220a90a387b28.gif

专栏:数学建模学习笔记

上一篇:【数学建模】图与网络模型的学习

本篇是题目练习

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

题目描述:

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

要求:

(1)使用Python编程,可以利用networkx库来构建图和处理图算法。

(2)绘制结果应包含所有节点(城市)和表示最短路径的边,边的粗细或颜色可以表示距离长短。

(3)标注每条边的权重(距离)。

(4)城市的数量N通过键盘输入,城市之间的距离通过随机数生成。

示例数据:

# 城市间的距离矩阵(假设为完全图,即任意两城市间都有直接路径)  

distances = [  

    [0, 5, 10, 15],  

    [5, 0, 3, 8],  

    [10, 3, 0, 6],  

    [15, 8, 6, 0]  

]  

# 假设城市名称为 A, B, C, D

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()

请输入城市数量: 5
城市间的距离矩阵:
[[ 0  3  6  1 16]
 [18  0  9 11  3]
 [16  2  0  5 11]
 [ 9  8  1  0 17]
 [ 2  7  1  3  0]]
请输入起始城市(A, B, C, D, E): A
从起始城市到其他城市的最短路径:
A到A的最短路径为['A'],距离为0
A到B的最短路径为['A', 'B'],距离为3
A到C的最短路径为['A', 'C'],距离为6
A到D的最短路径为['A', 'D'],距离为1
A到E的最短路径为['A', 'B', 'E'],距离为6

实现思想:

  1. 图的表示与构建

    • 使用图数据结构表示城市和它们之间的距离。节点表示城市,边的权重表示城市之间的距离。
    • 通过一个距离矩阵来表示各城市间的距离。
  2. Dijkstra算法

    • 用于计算从一个指定城市(源城市)到其他所有城市的最短路径。
    • 该算法适用于无负权边的图,通过贪心策略找到最短路径。
  3. 可视化

    • 使用 networkx 库构建图并计算最短路径。
    • 使用 matplotlib 库绘制图形,展示所有城市及其间的最短路径。

要点:

  1. 构建随机距离矩阵

    • 随机生成一个 N x N 的矩阵,表示 N 个城市间的距离。对角线元素为0(表示城市与自身的距离为0)。
  2. 构建图并添加边

    • 使用 networkx.Graph() 创建图对象。
    • 使用嵌套的 for 循环,将矩阵中的距离作为边的权重添加到图中。
  3. 计算最短路径

    • 使用 nx.single_source_dijkstra 函数,计算从指定源城市到所有其他城市的最短路径和路径长度。
  4. 绘制图形

    • 使用 nx.spring_layout 生成图节点的布局。
    • 使用 nx.drawnx.draw_networkx_edge_labels 绘制图和边的权重。
    • 突出显示最短路径,使用不同颜色或加粗显示。

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

题目描述:

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

要求:

(1)使用networkx库来处理图结构。

(2)绘制结果应清晰地展示MST中的所有边和顶点,并且可以通过边的颜色或粗细来区分MST中的边与其他边。

(3)标注MST的总权重。

示例数据:

# 边列表,每个元素是一个三元组(起点, 终点, 权重)  

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)  

]

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()

实现思想:

  1. 图的表示与构建

    • 使用图数据结构表示城市和它们之间的距离。节点表示城市,边的权重表示城市之间的距离。
    • 使用边列表表示图,其中每个元素是一个三元组 (起点, 终点, 权重)
  2. Kruskal算法

    • 用于找到图的最小生成树(MST)。
    • 通过贪心策略,逐步选择权重最小的边,构建权重和最小的树。
  3. 可视化

    • 使用 networkx 库构建图并计算MST。
    • 使用 matplotlib 库绘制图形,展示MST的所有节点和边。

要点:

  1. 定义边列表

    • 创建一个包含边的列表,每个元素是一个三元组 (起点, 终点, 权重)
  2. 构建图并添加边

    • 使用 networkx.Graph() 创建图对象。
    • 使用 G.add_weighted_edges_from(edges) 添加边到图中。
  3. 计算MST

    • 使用 nx.minimum_spanning_tree(G, algorithm='kruskal') 计算图的最小生成树。
  4. 绘制图形

    • 使用 nx.spring_layout 生成图节点的布局。
    • 使用 nx.drawnx.draw_networkx_edge_labels 绘制原始图及其边的权重。
    • 突出显示MST,使用不同颜色或加粗显示。

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

题目描述:

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

要求:

(1)绘制两个图:一个是MST,另一个是以核心城市为中心的最短路径图(可以只显示与核心城市直接相连的最短路径)。

(2)MST图中应清晰区分MST边和非MST边。

(3)最短路径图中,最短路径的边可以用特殊颜色或加粗显示,并标注核心城市到各城市的最短路径长度。

示例数据:

自行设计更复杂的数据集。

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()

实现思想: 

  1. 图的表示与构建

    • 使用图数据结构表示城市和它们之间的距离。节点表示城市,边的权重表示城市之间的距离。
    • 使用边列表表示图,其中每个元素是一个三元组 (起点, 终点, 权重)
  2. 计算MST

    • 使用 Kruskal算法计算图的最小生成树(MST)。
  3. 计算最短路径

    • 在MST的基础上,使用Dijkstra算法计算核心城市到其他所有城市的最短路径。
  4. 可视化

    • 绘制两个图:一个是MST,一个是核心城市的最短路径图。
    • 使用 networkx 库构建图并计算MST和最短路径。
    • 使用 matplotlib 库绘制图形,展示MST和最短路径。

要点:

  1. 定义边列表

    • 创建一个包含边的列表,每个元素是一个三元组 (起点, 终点, 权重)
  2. 构建图并添加边

    • 使用 networkx.Graph() 创建图对象。
    • 使用 G.add_weighted_edges_from(edges) 添加边到图中。
  3. 计算MST

    • 使用 nx.minimum_spanning_tree(G, algorithm='kruskal') 计算图的最小生成树。
  4. 计算最短路径

    • 使用 nx.single_source_dijkstra(mst, source=core_city) 在MST上计算核心城市到其他城市的最短路径。
  5. 绘制图形

    • 使用 nx.spring_layout 生成图节点的布局。
    • 使用 plt.figure 创建绘图窗口。
    • 使用 nx.drawnx.draw_networkx_edge_labels 绘制MST及其边的权重。
    • 突出显示最短路径,使用不同颜色或加粗显示路径边。

总结三个问题

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1954531.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前端 15】Vue生命周期

Vue生命周期 在Vue.js中,了解组件的生命周期对于开发者来说是至关重要的。Vue的生命周期指的是Vue实例从创建到销毁的一系列过程,每个阶段都对应着特定的生命周期钩子(或称为生命周期方法),允许我们在不同的时间点加入…

【中项】系统集成项目管理工程师-第7章 软硬件系统集成-7.2基础设施集成

前言:系统集成项目管理工程师专业,现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试,全称为“全国计算机与软件专业技术资格(水平)考试”&…

C#实现深度优先搜索(Depth-First Search,DFS)算法

深度优先搜索(DFS)是一种图搜索算法,它尽可能深入一个分支,然后回溯并探索其他分支。以下是使用C#实现DFS的代码示例: using System; using System.Collections.Generic;class Graph {private int V; // 顶点的数量pr…

牛客算法题解:数字统计、两个数组的交集、点击消除

目录 BC153 [NOIP2010]数字统计 ▐ 题解 NC313 两个数组的交集 ▐ 题解 AB5 点击消除 ▐ 题解 BC153 [NOIP2010]数字统计 题目描述: 题目链接: [NOIP2010]数字统计_牛客题霸_牛客网 (nowcoder.com) ▐ 题解 题目要求统计出某段数组中一共有多少个…

YOLOv8不同位置引入RepVGG重参数化

一、原理解析: 复杂的卷积网络大都具有如下缺点: 复杂的多分支设计(如ResNet中的残差相加和Inception中的分支连接)使模型难以实现和自定义,降低了推理速度和降低了内存利用率。一些组件(例如Xception和Mo…

嵌入式linux系统中压力测试的方法

在Linux环境下,确保系统各项资源充分且稳定地运行对任何系统管理员来说都至关重要。特别是在生产环境中,理解如何对系统资源进行基准测试和压力测试可以帮助预防未来的问题,同时也能够优化现有系统的性能。 在本文中,我们将探讨如何使用命令行工具来对Linux系统的CPU、内存…

开发环境搭建——Node.js

在启动前端项目的时候我们通常会用到Node.js,下面是对Node.js的下载安装以及配置的讲解 一、Node.js的安装 1.1、通过Node.js官网下载:Node.js — Run JavaScript Everywhere 下载后双击.msi安装文件后一直点击下一步即可 1.2、配置node 1.2.1、查看…

MT2140 供水管线(最小生成树Kruskal)

思路&#xff1a;Kruskal模板题 代码&#xff1a; #include<iostream> #include<stdio.h> #include<string.h> #include<vector> #include<algorithm> using namespace std;#define LL long long intconst int MAXN1e22;struct edge{int u,v,w;…

try-catch-finally 捕获异常不在catch里抛出;循环遍历对象生成任务,捕获异常对象不抛出,不影响其他正常对象生成任务

场景&#xff1a;一个模板绑定多个对象&#xff0c;要对每个对象生成任务。捕获生成任务过程中的异常&#xff0c;但是不抛出&#xff0c;只是用日志记录。这样做目的&#xff1a;循环遍历对象生成任务时&#xff0c;异常对象数据生成任务时发生异常只是导致自己生成任务失败&a…

29 列表元素访问

创建列表之后&#xff0c;可以使用整数作为下标来访问其中的元素&#xff1b;列表还支持使用负整数作为下标。 x list(hello world) print(x) print(x[0]) # 下标为0的元素&#xff0c;第一个元素 print(x[-1]) # 下标为-1的元素&#xff0c;最后一个元素x[5] print(x)

RedHat9 | Ansible 角色

环境版本说明 RedHat9 [Red Hat Enterprise Linux release 9.0]Ansible [core 2.13.3]Python [3.9.10]jinja [3.1.2] 描述角色结构 Playbook可能比较冗长且负载&#xff0c;也可能存在大量的重复代码。而角色&#xff08;roles&#xff09;可以用于层次性结构化的组织playbo…

【python】python生活管理费系统(源码+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

Python爬虫入门01:在Chrome浏览器轻松抓包

文章目录 爬虫基本概念爬虫定义爬虫工作原理爬虫流程爬虫类型爬虫面临的挑战 使用Chrome浏览器抓包查看网页HTML代码查看HTTP请求请求头&#xff08;Request Header&#xff09;服务器响应抓包的意义 爬虫基本概念 爬虫定义 爬虫&#xff08;Web Crawler 或 Spider&#xff0…

【JavaEE初阶】线程安全(重点)

目录 &#x1f4d5; 线程安全的概念 &#x1f384; 观察线程不安全 &#x1f333; 线程不安全的原因 &#x1f6a9; 原因&#xff1a; &#x1f332;解决之前的线程不安全问题 &#x1f6a9; synchronized 关键字 &#x1f4d5; 线程安全的概念 如果多线程环境下…

前端面经1

1、js是单线程还是多线程&#xff1f; 单线程执行。一次只能执行一个任务&#xff0c;处理任务的方式是通过一个任务队列&#xff08;也称为消息队列&#xff09;来实现的。如果某个操作&#xff08;如网络请求或定时器&#xff09;需要花费较长时间才能完成&#xff0c;它不会…

Flink SQL 的工作机制

前言 Flink SQL 引擎的工作流总结如图所示。 从图中可以看出&#xff0c;一段查询 SQL / 使用TableAPI 编写的程序&#xff08;以下简称 TableAPI 代码&#xff09;从输入到编译为可执行的 JobGraph 主要经历如下几个阶段&#xff1a; 将 SQL文本 / TableAPI 代码转化为逻辑执…

如何保证前后端交互信息不被篡改。

先说说前后端有哪些认证方式来保证&#xff1a; 基于 session 的认证方式&#xff1a;前端在用户登录成功后&#xff0c;后端会在服务器端生成一个唯一的 session ID&#xff0c;并将该 session ID 返回给前端&#xff0c;在后续的请求中&#xff0c;前端需要带上该 session ID…

【漏洞复现】蓝凌OA——远程命令执行

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现 漏洞描述 蓝凌OA平台&#xff0c;数字化向纵深发展&#xff0c;正加速构建产业互联…

图解分布式事务中的2PC与Seata方案

文章目录 文章导图什么是2PC解决传统2PC方案XA方案DTP模型举例&#xff1a;新用户注册送积分总结&#xff1a; Seata方案设计思想执行流程举例&#xff1a;新用户注册送积分 Seata实现2PC事务&#xff08;AT模式&#xff09;前提整体机制写隔离读隔离实际案例理解要点说明核心代…