本文为北海的数模课程学习笔记,课程出自微信公众号:数学建模BOOM。
求赞!求收藏!求关注!
目录
图论基本概念
作为软件工程专业的学生,在数据结构和离散数学中学了两遍。
单源最短路径
基本求解方法
基本性质
最短路径上的任一子路径也是最短路径(贪心算法和动态规划的基础)
常用算法
•
Dijkstra
算法(迪杰斯特拉算法),基于贪心思想
•
Floyd
算法,求出所有顶点对之间的最短路径,时间复杂度高
基本方法
调用MATLAB的shortestpath函数
•
根据题目画出图、写出邻接矩阵,调用函数即可
•
shortestpath
函数求
两个单一节点之间
的最短路径
对于做数模来说,掌握MATLAB函数求解即可
适用赛题
典型特征
从某个
“
起点
”
到某个
“
终点
”
,即始终围绕
“
起点到终点
”
的
“
总路径
”
求最优
例子
货物运输类问题
•
公路运输
/
铁路运输的路线固定,距离已知,每条路径耗费的费用已知
•
设计从
某点出发
,到达
终点
的运输路径,使总费用
/
路径最小
设备更新问题
•
购置新设备需要一笔费用,继续使用旧设备也需要支付维修费用且逐年增大
•
在
一定年限内
,如何安排购置新设备和使用旧设备,使总支付费用最小
典型例题
:以第二年年初买,使用到第五年初为例。
第二年年初购买:费用为11
第二年年初到第三年年初维修:费用为4
第三年年初到第四年年初维修:费用为5
第四年年初到第五年年初维修:费用为7
加起来总费用为27。但这并没有包含第一年年初到第二年年初和第五年年初到第五年年末。
代码实现
注意:MATLAB中,不存在的边(即邻接矩阵中正无穷)的权重写作0
完整代码
% 写出邻接矩阵,先定义全是0的矩阵,再修改不是0的元素
a = zeros(6);
a(1,[2:6])= [15 20 27 37 54];
a(2,[3:6]) = [15 20 27 37];
a(3,[4:6]) = [16 21 28];
a(4,[5:6]) = [16 21];
a(5,6) = 17;
% 给每个顶点标注名称,放在元胞s里(该部分不重要,不感兴趣可跳过)
% int2str([1:6]')将整数1到6六个数转化为字符
% strcat把字符串水平串联起来
% strcat('顶点',int2str([1:6]'))把"顶点"和字符1到6拼起来,
% 得到6行的数组,分别有v1,v2等
% 为何其中行向量[1:6]要转置成列向量?如果用行向量,则得到的是一行"v1 2 3 4 5 6"
s = cellstr(strcat('顶点',int2str([1:6]')));
G = digraph(a,s); % 不加s不影响求解
% plot绘图有很多参数可以设置,使图尽量美观
P = plot(G,'layout','force','EdgeColor','k','NodeFontSize',12);
[path,d] = shortestpath(G,1,6);
% 在图片P中,设置求得的最短路径path的属性(颜色、粗细等等)
highlight(P,path,"EdgeColor","red",'LineWidth',3.5)
代码解释
更改的图论的图布局,设置‘layout’。本代码中设置'layout','force',是实现在相邻节点之间使用引力,在远距离节点之间使用斥力。
更改图论图布局https://ww2.mathworks.cn/help/matlab/ref/matlab.graphics.chart.primitive.graphplot.layout.html?s_tid=doc_ta
求解得到的path=[1,3,6]意味着顶点1到顶点6的最短路径为1到3再到6;
d = 48意味着最短路径长度为48;
有关语法
graph:生成无向图
digraph:生成有向图
G = graph(A):使用邻接矩阵A创建无向图G,A中的元素值代表边的权重
G = graph(s,t,weights):使用顶点对组(两个矩阵)s,t和权重向量
最小生成树
模型简介
• 最小生成树 是从 全局角度考虑 ,使两两之间连通且 总路径最短 ,没有起点和终点的概念• 最短路径 是针对指定 源点(起点) 和指定 终点 ,求两点间 最短路径
典型例题
代码求解
写出邻接矩阵,调用函数(MATLAB的minspantree函数)即可。
clc,clear
% matlab中,不存在的边设置成0
% 9个顶点,初始化定义9x9的全零矩阵作为邻接矩阵
a = zeros(9);
% 注意,最小生成树是针对无向图的,每条边权重只需要设一次。1到2和2到1是同一条边
% 因此,可仅使用邻接矩阵的上三角矩阵来构造图G
a(1,[2:9])=[2 1 3 4 4 2 5 4]; % 顶点1到其他顶点的边的权重
a(2,[3 9])=[4 1]; % 顶点2到顶点3、顶点9的边的权重
a(3,4)=1; % 同上。因为写过1到3,和2到3的边的权重,无需重复设
a(4,5)=1;
a(5,6)=5;
a(6,7)=2;
a(7,8)=3;
a(8,9)=5;
% cellstr和graph在最短路径课程中讲过
s=cellstr(strcat('v',int2str([1:9]')));
G=graph(a,s,'upper'); % 仅使用 A 的上三角矩阵来构造图G。
p=plot(G,'EdgeLabel',G.Edges.Weight); % 绘制出图G
% minspantree函数求解最小生成树
% T=minspantree(G)是默认使用Prim算法
T=minspantree(G,'Method','sparse'); % 可指定使用Kruskal算法
L = sum(T.Edges.Weight) % 对最小生成树的边的权重求和
highlight(p,T,"EdgeColor","red",'LineWidth',2.5)