【数学建模】图论模型:从Dijkstra算法到最小费用最大流实战

 

💕个人主页Puszy-优快云博客💕

🎉 欢迎关注:👍点赞 📣留言 😍收藏 💖 💖 💖

赌书消得泼茶香,当时只道是寻常。 –– 《人民日报》

🌈🌈🌈往期精选:

💖【数学建模】主成分分析(PCA)详解:从理论到实践的全面指南-优快云博客

💖【数学建模】数据拟合与插值技术全解析:从线性插值到Logistic模型实战-优快云博客

💖【数学建模】熵权法——基于2021全国大学生数学建模C题供应商评价数学建模实战

💖基于PyTorch的MLP模型的MNIST手写数字识别的Python代码-优快云博客

目录

【数学建模】图论模型:从Dijkstra算法到最小费用最大流实战

💖引言

📚一、Dijkstra算法

🚀1.1、概念

🚀1.2、核心思想

🚀​1.3、重要概念介绍

📚二、案例分析

🚀2.1、最短路径类问题

📘2.1.1、题目一:企业设备更新计划

📄2.1.2、分析

🎉2.1.3、结果展示

📈2.1.4、代码展示

🚀2.2、最大费用最小流类问题

📘2.2.1、题目二:飞机行驶最优路径

📄2.3.2、分析

🎉2.3.3、结果展示

📈2.4.4、代码展示

📚参考链接


 

💖引言

        在我们这个高度互联的世界中,从社交网络到交通系统,从生物化学网络到互联网,图论模型无处不在。图论,这一数学分支,通过节点和边的简单概念,为我们提供了一种强大的工具,用以理解和分析复杂系统中的关系与结构。

        在本篇博客中,为了更好地理解图论模型,我将通过具体的题目来驱动对模型原理的探讨。例如,最短路径问题可以通过Dijkstra算法解决,该算法通过逐步扩展已知的最短路径,最终找到从起点到终点的最短路径。

📚一、Dijkstra算法

🚀1.1、概念

        迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。

🚀1.2、核心思想

        Dijkstra 算法的核心思想是 ​贪心策略​ 和 ​松弛操作,适用于 ​边权重非负​ 的有向或无向图。是其核心原理和思想的详细解释如下:

  1. 逐步逼近最优解
    从起点出发,逐步向外扩展,每次选择当前已知 ​最短路径​ 的节点,并更新其邻居节点的最短路径值。

  2. 贪心选择性质
    每次选择当前距离起点最近的未处理节点,假设该节点的当前最短路径已经是全局最优解(基于非负权重的假设)。

  3. 动态更新(松弛操作)​
    每当发现更短的路径时,更新节点的最短距离值。

🚀​1.3、重要概念介绍

邻接矩阵概念介绍:

流量矩阵概念介绍:

矩阵类型元素含义用途
邻接矩阵表示边的存在性或权重描述图的结构
流量矩阵表示边实际通过的流量分析最大流的具体分配

📚二、案例分析

🚀2.1、最短路径类问题

📘2.1.1、题目一:企业设备更新计划

        某企业使用一台设备,在每年年初都要决定是购置新设备还是继续使用旧的。购置新设备要支付一定的购置费,使用旧设备则要支付维修费。试制定一个五年的设备更新计划,使得总支付费用最少。己知该设备在各年年初的价格为:

第一年第二年第三年第四年第五年
1111121213

已知使用不同时间的设备每年维修费用为:

使用年数0-11-22-33-44-5
维修费用5681118

📄2.1.2、分析

         可以把这个间题化为图论中的最短路问题。构造赋权有向图 ,其中顶点集,这里 表示第 年初的时刻,表示第 5 年末的时刻 为弧的集合,邻接矩阵,这里 表示时刻 购置新设备使用到时刻 ,购置新设备的费用和维修费用之和。则邻接矩阵

则制定总的支付费用最小的设备更新计划,就是在有向图中求从的费用最短路。

🎉2.1.3、结果展示

        由图可以看出,第一年购买后维修两年,到第三年,再次购买设备,维修到第五年,费用最小,即

📈2.1.4、代码展示

import numpy as np
import networkx as nx
import pylab as plt

a=np.zeros((6,6))
a[0,1:]=[16,22,30,41,59]
a[1,2:]=[16,22,30,41]
a[2,3:]=[17,23,31]
a[3,4:]=[17,23]
a[4,5]=18
print(a)
G=nx.DiGraph(a)  #构造赋权有向图,顶点编号为0,1,…,5
p=nx.shortest_path(G,0,5,weight='weight')
d=nx.shortest_path_length(G,0,5,weight='weight')
print('path=',p); print('d=',d)
plt.rc('font',size=20)
pos=nx.shell_layout(G)  #设置布局
w=nx.get_edge_attributes(G,'weight')
key=range(6); s=['V'+str(i+1) for i in key]
s=dict(zip(key,s)) #构造用于顶点标注的字符字典
nx.draw(G, pos, font_weight='bold', labels=s, node_color='gray')
nx.draw_networkx_edge_labels(G, pos, edge_labels=w)
path_edges=list(zip(p, p[1:]))
nx.draw_networkx_edges(G, pos, edgelist=path_edges,
            edge_color='b', width=2)
plt.show()

🚀2.2、最大费用最小流类问题

📘2.2.1、题目二:飞机行驶最优路径

        在一次长距离空中演习过程中,战斗机从甲地出发,向目的地乙地飞行。由于战斗机的供油问题,因此需要在飞行一段时间后需要到特定地点进行加油,为保证不被敌军发现,每个航线的战斗机数量都有明确限制,具体单位战斗机飞行路线飞机数量与油耗如图1所示。如果你是这次演习中的指挥官,请设计一种方案,使得从甲地到乙地的战斗机数量最多,且耗油总量最少。

📄2.3.2、分析

        由数量最多,且耗油总量最少,可知,明显的最大最小流问题,可以使用Python的networkx包来解决该类问题。详细分析可参考代码逻辑。

🎉2.3.3、结果展示

📈2.4.4、代码展示

import networkx as nx
import numpy as np

# 创建有向图
G = nx.DiGraph()

# 添加边以及对应的容量(战斗机数量)和费用(燃料消耗)
edges = [
    (0, 1, 15, 8),
    (0, 2, 10, 10),
    (0, 3, 20, 15),
    (1, 4, 7, 9),
    (1, 5, 10, 11),
    (2, 5, 8, 8),
    (2, 6, 2, 6),
    (3, 6, 18, 14),
    (4, 7, 6, 8),
    (5, 7, 16, 9),
    (6, 7, 20, 10)
]

# 将边添加到图中
for u, v, capacity, cost in edges:
    G.add_edge(u, v, capacity=capacity, weight=cost)

# 计算从节点0到节点7的最大流和最小费用
flow_dict = nx.max_flow_min_cost(G, 0, 7)
total_flow = sum(flow_dict[0].values())
total_cost = nx.cost_of_flow(G, flow_dict)

print(f'从节点 0 到节点 7 的最大流和最小费用')
print(f'最大流:{total_flow}')
print(f'最小费用:{total_cost}')

# 导出顶点列表
node = list(G.nodes())
n = len(node)

# 创建流量矩阵
flow_mat = np.zeros((n, n))
for i, adj in flow_dict.items():
    for j, k in adj.items():
        flow_mat[node.index(i), node.index(j)] = k

print("最大流的流量为:", sum(flow_mat[:, -1]))
print("最小费用最大流的流量矩阵为:\n", flow_mat)

# 找到所有路径
paths = []
for i in range(n):
    for j in range(n):
        if flow_mat[i, j] > 0:
            paths.append((node[i], node[j], flow_mat[i, j]))

print("详细路径为:")
for path in paths:
    print(f"从 {path[0]} 到 {path[1]} 的流量为 {path[2]}")

📚参考链接

Python数学建模算法与应用_百度百科

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Puszy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值