数学建模学习记录——图与网络模型
一、图的基本概念
图论中的图(Graph)
是由若干给定的点及连接两点的线 所构成的图形,这种图形通常用来描述某些事物之间的某种 特定关系,用点代表事物,用连接两点的线表示相应两个事 物间具有这种关系。 一个图可以用数学语言描述为G(V(G),E(G))
。V(vertex)
指 的是图的顶点集,E(edge)
指的是图的边集。 根据边是否有方向,可将图分为有向图和无向图。 另外,有些图的边上还可能有权值,这样的图称为有权图。
写论文是可能需要用到的作图网站:https://csacademy.com/app/graph_editor/
Matlab作图
- 无向图
使用graph(s,t,w)
函数
% (1)无权重(每条边的权重默认为1)
% 函数graph(s,t):可在 s 和 t 中的对应节点之间创建边,并生成一个图
% s 和 t 都必须具有相同的元素数;这些节点必须都是从1开始的正整数,或都是字符串元胞数组。
s1 = [1,2,3,4];
t1 = [2,3,1,1];
G1 = graph(s1, t1);
plot(G1)
% 注意字符串元胞数组是用大括号包起来
s2 = {'学校','电影院','网吧','酒店'};
t2 = {'电影院','酒店','酒店','KTV'};
G2 = graph(s2, t2);
plot(G2, 'linewidth', 2) % 设置线的宽度
% 下面的命令是在画图后不显示坐标
set( gca, 'XTick', [], 'YTick', [] );
% (2)有权重
% 函数graph(s,t,w):可在 s 和 t 中的对应节点之间以w的权重创建边,并生成一个图
s = [1,2,3,4];
t = [2,3,1,1];
w = [3,8,9,2];
G = graph(s, t, w);
plot(G, 'EdgeLabel', G.Edges.Weight, 'linewidth', 2)
set( gca, 'XTick', [], 'YTick', [] );
- 有向图
使用digraph(s,t,w)
函数
% 有权图 digraph(s,t,w)
s = [1,2,3,4];
t = [2,3,1,1];
w = [3,8,9,2];
G = digraph(s, t, w);
plot(G, 'EdgeLabel', G.Edges.Weight, 'linewidth', 2)
set( gca, 'XTick', [], 'YTick', [] );
权重邻接矩阵
-
有向图
-
无向图
二、单源最短路问题
迪杰斯特拉算法
注意:迪杰斯特拉算法不适用于带负权重的图。存在负权回路的图是不能求两点间最短路的。
Matlab计算最短路径
-
函数:
[P,d] = shortestpath(G,start,end[,'Method',algorithm] )
-
输入参数:
(1)G ‐输入图(graph 对象| digraph 对象)
(2)start 起始的节点
(3)end 目标的节点
(4)[,‘Method’,algorithm]是可选的参数,表示计算最短路径的算法。一般我们不用手动设置,默认使用的是“auto”
-
输出参数:
(1)P –最短路径经过的节点
(2)d –最短距离
-
可选算法:
选项 | 说明 |
---|---|
'auto'(默认值) | ‘auto’ 选项会自动选择算法: 'unweighted' 用于没有边权重的graph 和digraph 输入。 'positive' 用于具有边权重的所有graph 输入,并要求权 重为非负数。此选项还用于具有非负边权重的digraph 输 入。 'mixed' 用于其边权重包含某些负值的digraph 输入。图 不能包含负循环。 |
'unweighted' | 广度优先计算,将所有边权重都视为1。 |
'positive' | Dijkstra 算法,要求所有边权重均为非负数。 |
'mixed'(仅适用于digraph) | 适用于有向图的Bellman‐Ford 算法,要求图没有负循环。 尽管对于相同的问题,'mixed' 的速度慢于'positive' ,但 'mixed' 更为通用,因为它允许某些边权重为负数。 |
-
返回距离矩阵
函数:d = distances(G [,'Method',algorithm])
-
找给定范围内所有的点
函数:[nodeIDs,dist] = nearest(G,s,d[,'Method',algorithm])
返回图形G
中与节点s
的距离在d
之内的所有节点。nodeIDs
是符合条件的节点,Dist
是这些节点与s
的距离。
三、网络最大流问题
定义:
最大流问题就是求一个流
{
f
i
j
}
\{ f_{ij} \}
{fij}使其流量
v
(
f
)
v(f)
v(f)达到最大,可以写成如下的线性规划模型:
m
a
x
{
v
(
f
)
}
max \{v(f)\}
max{v(f)}
0 ≤ f i j ≤ c i j , ( v i , v j ) ∈ A 0≤f_{ij}≤c_{ij}, (vi,vj)∈A 0≤fij≤cij,(vi,vj)∈A
∑ f i j − ∑ f j i = { v ( f ) , ( i = s ) 0 , ( i ≠ s , t ) − v ( f ) , ( i = t ) \sum{f_{ij}}-\sum{f_{ji}}=\left\{ \begin{aligned} v(f),(i=s) \\ 0,(i≠s,t) \\ -v(f),(i=t) \end{aligned} \right. ∑fij−∑fji=⎩⎪⎨⎪⎧v(f),(i=s)0,(i=s,t)−v(f),(i=t)
Matlab求解:
函数:[MaxFlow, FlowMatrix, Cut] = graphmaxflow(G, SNode,TNode)
该命令只能求解权重都为正值,且两个顶点之间不能有两条弧的问题,若要解决两条弧的问题,可以加入虚拟的顶点
四、MatLab图论工具箱
MATLAB内有图论工具箱,可以很好的解决图论的问题,减少了自己学习算法和代码的难度