浅尝辄止_数学建模(笔记_图论基本知识+最短路径算法)

图论

一、图的基本概念

 图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物之间具有这种关系。
 一个图可以用数学语言描述为G(V(G),E(G))。V(vertex)指的是图的顶点集,E(edge)指的是图的边集。
 根据是否有方向,可将图分为有向图和无向图(有向图的特例,无向图可以看作边全为双向箭头的有向图)。另外,有些图的边上还可能有权值,这样的图称为有权图。


二、制图方法

1. 利用制图网站

CS Academy简单易操作。(强烈推荐)


2. Matlab作图

G1 = graph(s1,t1);
plot(G1)
//graph(s,t)函数可以在s和t中的对应节点之间建立边,并生成一个图。
//s,t都是矩阵,且必须具有相同的元素数,这些节点必须都是从1开始的正整数(中括号),或都是字符串元胞数组(大括号)。
G2 = graph(s,t,w);
plot(G2)
//graph(s,t,w)可以在s和t中对应节点之间以w为权重创建边,并生成一个图。
//s,t都是矩阵,且必须具有相同的元素数,这些节点必须都是从1开始的正整数(中括号),或都是字符串元胞数组(大括号)。
plot(G2,'linewidth',2)
//设置线的宽度,此时不会显示权重
plot(G,'EdgeLabel',G.Edges.Weight,'linewidth',2)
//显示带有权重的图

注意:编号最好是从1开始连续编号,不要自己随便定义编号,并顺带以下代码。
 
有向图的制图代码:有向图和无向图在代码中的区别在于graph和digraph

set(gca,'XTick',[],'YTick',[]);
//此命令是在画图后不显示坐标的函数
myplot=plot(G,'EdgeLabel',G.Edges.Weight,'linewidth',2);
 //首先将图赋给一个变量
hightlight(myplot,P,'EdgeColor','r')
//在图形中用红色高亮最短路径

三、权重邻接矩阵

1.无向图的权重邻接矩阵

  • 无向图对应的权重邻接矩阵D是一个对称矩阵
  • 其主对角线上元素为0
  • D_ij表示第i个节点到第j个节点的权重
  • l n f lnf 表示两节点之间无边

2.有向图的权重邻接矩阵

  • 有向图对应的权重邻接矩阵D一般不再是对称矩阵
  • 其主对角线上元素为0
  • D_ij表示第i个节点到第j个节点的权重
  • l n f lnf 表示两节点之间无边

四、迪杰斯特拉算法

目的:
求解最短距离,迪杰斯特拉算法是最短距离算法的一种。
 
缺点:
没有办法处理负权重
 
具体讲解:
图论最短距离(Shortest Path)算法动画演示-Dijkstra(迪杰斯特拉)和Floyd(弗洛伊德)
 
优化算法(解决负权重的算法):
贝尔曼-福特算法(Bellman–Ford algorithm )油管最好的三个讲解
贝尔曼福特算法一定程度上解决了迪杰斯特拉算法的缺点,即处理了具有负权重的有向图,但是依旧不支持处理拥有负权回路的图
 
负权回路知识补充:

  • 在一个图里每条边都有一个权值(有正有负)。如果存在一个环(从某点出发又回到自己的路径),而且这个环上所有权值之和为负数,那就是一个负权环,也叫负权回路。
  • 含有负权重的无向图都是负权回路。
  • 存在负权回路的图是不能求两点间最短路径的,因为只要在负权回路不断兜圈子,所得的最短路长度可以任意小。

五、Matlab运用

1.计算最短路径

[p , d] = shortestpath(G,start,end [,'Method',algorithm])

功能:
返回图G中start节点到end节点的最短路径
 
输入参数:

  1. G — 输入图(graph对象 | digraph对象)
  2. start 起始的节点
  3. end 目标的节点
  4. [,‘Method’,algorithm]是可选的参数,表示计算最短距离的算法。

对于4中可选的参数如下表格所示:

选项 说明
'auto'(默认值) 'auto'选项会自动选择算法。
'unweight' 用于没有边权重的graph和digraph输入,广度优先计算,将所有边权重都视为1。
'positive' 用于具有边权重的所有graph输入,并要求权重为非负数。此选项还用于具有非负边权重的digraph输入。(迪杰斯特拉算法)
'mixed'(仅适用于digraph) 用于其边权重包含某些负值的digraph输入(图不能含有负权回路),适用于有向图的贝尔曼福特算法。

输出数据:

  1. P — 最短路径经过的节点
  2. d — 最短路径

2.返回任意两点的距离矩阵

D = distances(G [,'Method',algorithm])
//返回任意两点的距离矩阵
D(1,2)
//1到2的最短距离
D(9,4)
//9到4的最短距离

3.找给定范围内所有的点

[nodeIDs,dist] = nearest(G,s,d [, 'Method',algorithm])

返回图形G中与节点s的距离在d之内的所有节点;
nodeIDs是符合条件的节点;
dist是这些节点与s的距离。

猜你喜欢

转载自blog.csdn.net/ICISTRUE/article/details/108285308