打卡第五天,图的最短路径和距离

一、最短路径

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为距离。

 

上一篇:Rust中语句和表达式的区别


下一篇:mysql-终端链接mysql报错