图的最短路径和距离

关于图的最短距离和路径问题的原理层面,离散数学和数据结构中都有详解这里我们不做详细的剖析,如果不太清楚,可以参考下这篇文章,虽然有一点点小笔误当然,这篇文章主要介绍的是迪杰特斯拉算法的一个计算过程,因为我们本篇文章记录的主要是graphallshortestpath和dijkstra两个函数的用法,其内部逻辑主要就是基于迪杰特斯拉算法。至于弗洛伊德算法什么的,我们暂时不做讨论。

sparse创建稀疏矩阵

使用sparse创建稀疏矩阵,一般有以下两种方式

 w=zeros(4);
 w(1,1)=1;w(1,4)=5;w(2,4)=8;w(4,2)=6;w(3,3)=9;
 G=sparse(w)

G =

   (1,1)        1
   (4,2)        6
   (3,3)        9
   (1,4)        5
   (2,4)        8
 w0=zeros(4);
G0=sparse([1 4 3 1 2],[1 2 3 4 4 ],[1 6 9 5 8])

G0 =

   (1,1)        1
   (4,2)        6
   (3,3)        9
   (1,4)        5
   (2,4)        8

一、最短路径之graphallshortestpaths


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'))
%这里面我们通过biograph可以生成一个图的对象。其中参数G是我们生成的稀疏矩阵
%'Showeights','on'('off'),表示显示(不显示)权重;同理'Showarrows','on'('off')则表示
%是否显示箭头,即是不是有向图
graphallshortestpaths(G)

在这里插入图片描述
这是我们上面代码产生的结果,graphallshortestpaths(G)所产生的矩阵直观地体现了每一对顶点对之间的最短距离。它既可以求无向图最短路径也可以求有向图最短路径,由’directed’true或者’false’来决定。无向时显然得到的是一个对角线为0的对称矩阵。
关于图论问题的几个常用函数用法可以参考这篇文章

二、最短路径之dijkstra

% 构造邻接矩阵
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; % 零元素换成inf
a(eye(6,6)==1)=0; % 对角线换成 0 
view(biograph(a,[],'ShowWeights','on'))
[min,path]=dijkstra(a,1,6) % dijkstra模型求解节点一到节点六最短路径

以上代码是我希望得到像这篇博客一样的效果用的,结果用的时候发现我的matlab自带的有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);

他可以返回指定顶点对之间的最小距离,以及实现该距离的路径。也是用来解决有向图问题的。

无向图最短路径之shortestpath

请添加图片描述
请添加图片描述
显然这个函数跟我们上面改造的dijkstra函数的用法和结果都一样。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

公子小白痴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值