图论最短路径问题
本讲将简要介绍图论中的基本概念,并主要讲解图论中的最短路径问题。根据图的不同,将学习两种不同的算法:迪杰斯特拉Dijkstra算法
图的基本概念
- 两种画图方法
- 一个画图的网站(推荐使用)
- MATLAB画图
% 函数graph(s,t):可在 s 和 t 中的对应节点之间创建边,并生成一个图
G1 = graph(s1, t1);
plot(G1)
% 函数graph(s,t,w):可在 s 和 t 中的对应节点之间以w的权重创建边,并生成一个图
G2 = graph(s2, t2);
plot(G2, 'linewidth', 2) % 设置线的宽度
% 下面的命令是在画图后不显示坐标
set( gca, 'XTick', [], 'YTick', [] );
以上都是画无向图,要做出有向图,只需要将graph改为digraph就行了。
- 图的邻接矩阵
- 无向图的权重邻接矩阵
- 无向图对应的权重邻接矩阵D是一个对称矩阵
- 其主对角线上元素为0
- D i j D_{ij} Dij表示第 i i i个节点到第 j j j个节点的权重
- 有向图的权重邻接矩阵
- 有向图对应的权重邻接矩阵D是一般不再是对称矩阵
- 其主对角线上元素为0.
- D i j D_{ij} Dij表示第 i i i个节点到第 j j j个节点的权重。
迪杰斯特拉算法
- 主要思路 :每一步都是“最短路径”
- 指定一个起点D(即从顶点D开始计算)。
- 引进两个数组记录是否访问&&最短距离
- 从距离最短的点,把此点标记为访问过且开始更新其临近点的最小路径。
- 重复3直到所有都访问过
- 缺陷 :但不能处理负权重
这里可用Bellman‐Ford(贝尔曼‐福特)算法解决
贝尔曼‐福特算法不再将节点区分为是否已访问的状态,利用循环来进行更新权重的,且每循环一次,贝尔曼福特算法都会更新所有的节点的信息。
-
MATLAB实现
[P,d] = shortestpath(G,start,end [,'Method',algorithm] )
功能:返回图G中start节点到end节点的最短路径
输入参数:- G ‐ 输入图(graph 对象 | digraph 对象)
- start 起始的节点
- end 目标的节点
- [,‘Method’,algorithm]是可选的参数,表示计算最短路径的算法。一般不用手动设置,默认使用的是“auto”。
输出参数:
- P – 最短路径经过的节点
- d – 最短距离
另外两种最短距离
- 返回任意两点的距离矩阵
d = distances(G [,'Method',algorithm])
- 找给定范围内所有的点
[nodeIDs,dist] = nearest(G,s,d [,'Method',algorithm])
返回图形 G 中与节点 s 的距离在 d 之内的所有节点。
nodeIDs是符合条件的节点
Dist是这些节点与s的距离