目录
·图的基本概念
一个图G是一个三元组,这个三元组包含一个顶点集V(G),一个边集E(G)和一个关系,该关系使得每一条边和两个顶点相关联,并将这两个顶点称为这条边的端点。
通俗来解一个图需要有点(顶点集V(G))、点与点之间的连线(E(G))、线长(关系)组成。自然界与人类社会中大量的人与事物之间的关系都可以用图形来描述,如分配工作、电路网络、城市规划、交通运输、信息传递、物资调配等也都可以用这样的点和线来进行模拟。
定义:无向图G中,连接,的一条链,当为同一点时,称此链为圈,圈中既无重复点,又无重复边者为初等圈。
·应用场景
1.最短路径问题
如图1-1,有六个顶点(顶点集V(G)),9条连线(E(G))与其对应的线长(关系),如何求任意两点的最短路径?
图1-1
2.树
图1-2
如图1-2是一个典型的树,有分支,有叶,在实际的问题中,如交通系统中设计长度最小的公路网把若干城市连接起来;通信系统中用最小成本将计算机系统和设备连接到局域网等等都可以用最小数问题解决。
3.最大流问题
最大流问题是一类应用极为广泛的问题,例如在交通网络中有人流、车流、货物流,供水网络中有水流,金融系统中有现金流,通信系统中有通信流等等。20世纪50年代福特(Ford),福克逊(Fulkerson)建立的“网络流理论”,是网络应用的重要组成部分。
图1-3
我们把图1-3看作输油管道网,6为起点,5为终点,1,2,3,4为中转站,边上的数表示了该管道的最大输油能力,问如何安排各个管道输油量,使得6——>5的总输油量最大?
·MATLAB解决方案
MATALB中关于图论的常用函数,如下表:
函数 | 功能 |
graphallshortestpaths | 求图中所有顶点对之间的最短距离 |
graphisspantree | 确定一个图是否是生成树,是返回1,否则返回0 |
graphmaxflow | 计算有向图的最大流 |
graphminspantree | 在图中找最小生成树 |
graphshortestpath | 求图中指定的一对顶点间的最短距离和最短路径 |
1.最短路径问题——graphallshortestpaths、graphshortestpath
解决图1-1的最短路径问题
上源代码:
data = [1 2 3
1 5 4
1 6 7
2 3 7
2 4 9
2 5 6
3 4 3
4 5 4
5 6 1]; %输入邻接矩阵
start=data(:,1); %起点编号
endot=data(:,2); %终点编号
weight=data(:,3); %连接起点和终点的边权重
graphsize=max(max(start),max(endot));
%更新距离矩阵
DG = sparse(start,endot,weight,graphsize,graphsize);%求稀疏矩阵
g = tril(DG+DG');%取矩阵和转置矩阵和的下三角矩阵
%这一步的目的是要把稀疏矩阵化为无向
h = view(biograph(g,[],'ShowWeights','on','ShowArrows','off'));
dist = graphallshortestpaths(g);
dist = tril(dist)+tril(dist)'
运行结果:
图1-4
dist =
0 3 10 12 4 5
3 0 7 9 6 7
10 7 0 3 7 8
12 9 3 0 4 5
4 6 7 4 0 1
5 7 8 5 1 0
dist(A,B)为AB两点的最小距离
如dist(6,1)意为6——>1的最小距离为5
graphallshortestpaths的优点是可以很清晰的看清楚任意两点的最短距离,缺点是不能查询具体路径,如果要查询具体路径要用到graphshortestpath函数。
使用方法与graphallshortestpath类似
代码:
data = [1 2 3
1 5 4
1 6 7
2 3 7
2 4 9
2 5 6
3 4 3
4 5 4
5 6 1]; %输入邻接矩阵
start=data(:,1); %起点编号
endot=data(:,2); %终点编号
weight=data(:,3); %连接起点和终点的边权重
graphsize=max(max(start),max(endot));
%更新距离矩阵
DG = sparse(start,endot,weight,graphsize,graphsize);%求稀疏矩阵
g = tril(DG+DG');%取矩阵和转置矩阵和的下三角矩阵
%这一步的目的是要把稀疏矩阵化为无向
h = view(biograph(g,[],'ShowWeights','on','ShowArrows','off'));
[dist,path] = graphshortestpath(g,1,6,'Directed',false,'Method','Dijkstra')%从1——>6的最短路径
运行结果
dist =
5
path =
1 5 6
可以看到最短路径为1——>5——>6
2.树——graphisspantree、graphminspantree
TF = graphisspantree(DG)
输入稀疏矩阵,判断此矩阵是否为树
[tree,pred] = graphminspantree(DG)
输入稀疏矩阵,输出最小树与节点信息
一个乡有9个自然村,其间道路及道路长如图1-5所示,边上数字表示距离,问如何架线使得村村通电同时用线最短?
图1-5
MATLAB代码
clear all
data = [1 2 4
1 8 1
1 9 2
2 3 1
2 9 1
3 4 1
3 9 3
4 9 4
4 5 5
5 6 2
5 9 4
6 7 3
6 9 2
7 8 5
7 9 5
8 9 4];
start=data(:,1); %起点编号
endot=data(:,2); %终点编号
weight=data(:,3); %连接起点和终点的边权重
graphsize=max(max(start),max(endot));
%更新距离矩阵
DG = sparse(start,endot,weight,graphsize,graphsize);%求稀疏矩阵
g = tril(DG+DG');%取矩阵和转置矩阵和的下三角矩阵
%这一步的目的是要把稀疏矩阵化为无向
h = view(biograph(g,[],'ShowWeights','on','ShowArrows','off'));%DG是得到的稀疏矩阵,如果显示边的值,就第一个设为on,如果是有向图第二个就设为on
TF(1) = graphisspantree(g);%验证g是否为树
[tree,pred] = graphminspantree(g);
TF(2) = graphisspantree(tree);%验证tree是否为树
h = view(biograph(tree,[],'ShowWeights','on','ShowArrows','off'));%DG是得到的稀疏矩阵,如果显示边的值,就第一个设为on,如果是有向图第二个就设为on
Edges=getedgesbynodeid(h);%提取无向图h的边集
set(Edges,'LineColor',[0 0 0]);%设置颜色属性
set(Edges,'LineWidth',1.5)%设置边值属性
代码运行结果:
tree =
(8,1) 1
(9,1) 2
(3,2) 1
(9,2) 1
(4,3) 1
(6,5) 2
(7,6) 3
(9,6) 2
图1-6
图1-7
最终方案如图1-7,可以看出最小权为13。
3.最大流问题——graphmaxflow
[MaxFlow,FlowMatrix,Cut]=graphmaxflow(G,startpoint,endpoint)
各个变量的含义为字面意思
FlowMatrix:满足最大流的稀疏矩阵
Cut:路径
PS:graphmaxflow有一个缺点就是无法计算可逆项,比如图1-3中3——>4和4——>3有两条可逆的路径,这时候graphmaxflow就会报错:Reciprocal edges are not allowed in maxflow algorithms.
我的解决方案是去掉一组数据后计算两次然后比较
clear all
data = [1 2 2
1 3 1
2 3 2
2 6 4
%3 4 3 %第二次计算去掉4,3,2,比较二者大小
3 6 2
4 3 2
4 6 3
5 1 4
5 3 3
5 4 4];
start=data(:,1); %起点编号
endot=data(:,2); %终点编号
weight=data(:,3); %连接起点和终点的边权重
graphsize=max(max(start),max(endot));
%更新距离矩阵
DG = sparse(start,endot,weight,graphsize,graphsize);%求稀疏矩阵
h = view(biograph(DG,[],'ShowWeights','on','ShowArrows','on'));%DG是得到的稀疏矩阵,如果显示边的值,就第一个设为on,如果是有向图第二个就设为on
[MaxFlow,FlowMatrix,Cut] = graphmaxflow(DG,5,6); %计算从5到6的最大流
h = view(biograph(FlowMatrix,[],'ShowWeights','on','ShowArrows','on'));%最大流图像
代码运行结果:
MaxFlow =
7
FlowMatrix =
(5,1) 2
(1,2) 2
(5,3) 2
(5,4) 3
(2,6) 2
(3,6) 2
(4,6) 3
图1-8
图1-9
参考文献:
[1]胡运权,郭耀煌.运筹学教程[M].北京:清华大学出版社,2018:222-243
[2]Douglas B.West[美].图论导引[M].北京.机械工业出版社,2006