一、最短路径
1、sparse建立稀疏矩阵
用川川给的案例建立稀疏矩阵,有两种方法
clc
clear
w=zeros(4);
w(1,2)=2;
w(1,3)=3;
w(2,3)=6;
w(2,4)=6;
w(1,4)=8;
G=sparse(w)
第一种方法我的理解建立一个零矩阵,将每个每条路径的值存放进矩阵中,在使用sparse建立稀疏矩阵。w的矩阵是这样的:
运行结果为:
第二种方法是sparse建立稀疏矩阵,用法:sparse([起点矩阵],[终点矩阵],[对应的权重]),
代码如下:
clc
clear
G=sparse([1 1 1 2 2],[2 3 4 3 4],[2 3 8 6 6]);
s=sparse(G)
运行结果为:
2、有向图最短路径
使用graphallshortestpaths函数,语法为:
[dist
] = graphallshortestpaths(G
)
[dist
] = graphallshortestpaths(G
, ...'Directed', DirectedValue
, ...)
[dist
] = graphallshortestpaths(G
, ...'Weights', WeightsValue
, ...)
G代表稀疏矩阵,0或false代表无向图,1或true代表有向图。默认为有向图。
先创建一个有向图,
clc
clear
G=sparse([6 1 2 2 3 4 4 5 5 6 1],[2 6 3 5 4 1 6 3 4 3 5],[41 99 51 32 15 45 38 32 36 29 21]);
view(biograph(G,[],'ShowWeights','on'))
得到一个有向图
再使用graphallshortestpaths函数求最短路径
clc
clear
G=sparse([6 1 2 2 3 4 4 5 5 6 1],[2 6 3 5 4 1 6 3 4 3 5],[41 99 51 32 15 45 38 32 36 29 21]);
view(biograph(G,[],'ShowWeights','on'))
graphallshortestpaths(G)
运行结果为:
第一列表示节点一到节点六的距离,第一个元素为零,意思是第一节点到第一节点为零,所以这一条对角线的值都为零,第二行第一列为111,表示第二节点到第一节点的距离,路径为2到3到4到1,结果就是51+15+45=111。
二、求最短路径(二)
第二种方法求有向图最短距离,使用dijkstra函数
function [min,path]=dijkstra(w,start,terminal)
n=size(w,1); label(start)=0; f(start)=start;
for i=1:n
if i~=start
label(i)=inf;
end, end
s(1)=start; u=start;
while length(s)<n
for i=1:n
ins=0;
for j=1:length(s)
if i==s(j)
ins=1;
end
end
if ins==0
v=i;
if label(v)>(label(u)+w(u,v))
label(v)=(label(u)+w(u,v));
f(v)=u;
end
end
end
v1=0;
k=inf;
for i=1:n
ins=0;
for j=1:length(s)
if i==s(j)
ins=1;
end
end
if ins==0
v=i;
if k>label(v)
k=label(v); v1=v;
end
end
end
s(length(s)+1)=v1;
u=v1;
end
min=label(terminal); path(1)=terminal;
i=1;
while path(i)~=start
path(i+1)=f(path(i));
i=i+1 ;
end
path(i)=start;
L=length(path);
path=path(L:-1:1);
说实话不是很看得懂这个函数 :),只知道用这个函数能更快更简单求最短路径,,,
求和上面一样的问题,代码为:
a=zeros(6);
a=sparse([6 1 2 2 3 4 4 5 5 6 1],[2 6 3 5 4 1 6 3 4 3 5],[41 99 51 32 15 45 38 32 36 29 21]);
a=a+a';
a(a==0)=inf;
a(eye(6,6)==1)=0;
view(biograph(a,[],'ShowWeights','on'))
[min,path]=dijkstra(a,1,6)
我的理解是写出每两个节点之间的距离,没有路径的距离就是无限,运行结果为:
节点一到节点六的路径为1 5 3 6;
但是这里有一个疑问,我觉得这个方法解出来的应该是无向的最小值 ,图像绘制出来也是两个箭头,我认为两个箭头就和无向一样了,所以才有1 5 3 6的路径,原来我们的图
只能6到3,不能3到6,所以节点一到节点六之间的路径必须是1 5 4 6,路径最短为95。这个疑问请川佬给我解答一下(感谢)。
三、求无向的最小值
还是用上边的代码,关闭箭头
clear all
clc
W = [41 99 51 32 15 45 38 32 36 29 21];
G = sparse([6 1 2 2 3 4 4 5 5 6 1],[2 6 3 5 4 1 6 3 4 3 5],W)
UG = tril(G + G')
view(biograph(UG,[],'ShowArrows','off','ShowWeights','on'))
结果为:
在使用graphallshortestpaths函数求最小值
运行结果为:
节点一到节点六最短距离为82,路径为1 5 3 6;
无向图还可以使用shortestpaths函数求路径最小值,
clc
clear
G=zeros(6);
G=graph([6 1 2 2 3 4 4 5 5 6 1],[2 6 3 5 4 1 6 3 4 3 5],[41 99 51 32 15 45 38 32 36 29 21])
plot(G,'EdgeLabel',G.Edges.Weight)
[P,d]=shortestpath(G,1,6)
代码运行结果为:
P就是路径,d为距离。