图论Ⅱ——Matlab中的遍历、最短路径和最大流
图论Ⅱ——Matlab中的遍历、最短路径和最大流
Matlab中图和网络算法函数
构造 | |
---|---|
graph | 具有无向边的图 |
digraph | 具备有向边的图 |
修改节点和边 | |
---|---|
addnode | 将新节点添加到图 |
rmnode | 从图中删除节点 |
addedge | 向图添加新边 |
rmedge | 从图中删除边 |
flipedge | 反转边的方向 |
numnodes | 图中节点的数量 |
numedges | 图中边的数量 |
findnode | 定位图中的节点 |
findedge | 定位图中的边 |
edgecount | 两个节点之间的边数 |
reordernodes | 对图节点重新排序 |
subgraph | 提取子图 |
分析结构 | |
---|---|
centrality | 衡量节点的重要性 |
conncomp | 图的连通分量 |
biconncomp | 双连通图分量 |
condensation | 图凝聚 |
bctree | 块割点树图 |
toposort | 有向无环图的拓扑顺序 |
isdag | 确定图是否为无环 |
transreduction | 传递归约 |
transclosure | 传递闭包 |
isisomorphic | 确定两个图是否同构 |
isomorphism | 计算两个图之间的同构 |
ismultigraph | 确定图是否具有多条边 |
simplify | 将多重图简化为简单图 |
遍历、最短路径和循环 | |
---|---|
bfsearch | 广度优先图搜索 |
dfsearch | 深度优先图搜索 |
shortestpath | 两个单一节点之间的最短路径 |
shortestpathtree | 从节点的最短路径树 |
distances | 所有节点对组的最短路径距离 |
allpaths | 查找两个图节点之间的所有路径 |
maxflow | 图中的最大流 |
minspantree | 图的最小生成树 |
hascycles | 确定图是否包含循环 |
allcycles | 查找图中的所有循环 |
cyclebasis | 图的基础循环基 |
矩阵表示 | |
---|---|
adjacency | 图邻接矩阵 |
incidence | 图关联矩阵 |
laplacian | 图拉普拉斯矩阵 |
节点信息 | |
---|---|
degree | 图节点的度 |
neighbors | 图节点的相邻节点 |
nearest | 半径范围内最近的邻点 |
indegree | 节点的入度 |
outdegree | 节点的出度 |
predecessors | 前趋节点 |
successors | 后继节点 |
inedges | 进入节点的入向边 |
outedges | 节点的出向边 |
可视化 | |
---|---|
plot | 绘制图节点和边 |
labeledge | 为图边添加标签 |
labelnode | 为图节点添加标签 |
layout | 更改图论图布局 |
highlight | 突出显示绘制的图中的节点和边 |
bfsearch——广度优先图搜索;dfsearch——深度优先搜索
语法及说明
v = bfsearch(G,s) %将广度优先搜索应用于图 G,从节点 s 开始。结果是按发现顺序排序的节点 ID 向量。 T = bfsearch(G,s,events) %通过标记一个或多个搜索事件,自定义广度优先搜索的输出。例如,T = bfsearch(G,s,'allevents') 返回一个表,其中包含所有已标记的事件,X = bfsearch(G,s,'edgetonew') 返回边的矩阵或元胞数组。 [T,E] = bfsearch(G,s,events) [___] = bfsearch(___,'Restart',tf)
示例
执行广度/深度优先图搜索:
创建并绘制一个图
s = [1 1 1 1 2 2 2 2 2]; t = [3 5 4 2 6 10 7 9 8]; G = graph(s,t); plot(G)
从节点2处开始执行图的广度优先搜索。结果指示节点的发现顺序。
v = bfsearch(G,2)
v = 2 1 6 7 8 9 10 3 4 5
从节点 7 开始对图执行深度优先搜索。结果指示节点发现顺序。
v = dfsearch(G,7)
v = 7 2 1 3 4 5 6 8 9 10
shortestpath——两个单一节点之间的最短路径
语法及说明
P = shortestpath(G,s,t) %计算从源节点 s 处开始到目标节点 t 处结束的最短路径。如果图进行了加权(即 G.Edges 包含变量 Weight),则这些权重用作沿图中各边的距离。否则,所有边距离都视为 1。 P = shortestpath(G,s,t,'Method',algorithm) %可选择性地指定在计算最短路径时使用的算法。 [P,d] = shortestpath(___) %还使用上述语法中的任何输入参数返回最短路径的长度 d。 [P,d,edgepath] = shortestpath(___) %还返回从 s 到 t 的最短路径上所有边的边索引 edgepath。
示例
指定节点之间的最短路径:
创建并绘制一个有向图。
s = [1 1 2 3 3 4 4 6 6 7 8 7 5]; t = [2 3 4 4 5 5 6 1 8 1 3 2 8]; G = digraph(s,t); plot(G)
计算节点 7 和 8 之间的最短路径。
P = shortestpath(G,7,8)
P = 7 1 3 5 8
加权图中的最短路径:
创建并绘制一个具有加权边的图。
s = [1 1 1 2 2 6 6 7 7 3 3 9 9 4 4 11 11 8]; t = [2 3 4 5 6 7 8 5 8 9 10 5 10 11 12 10 12 12]; weights = [10 10 10 10 10 1 1 1 1 1 1 1 1 1 1 1 1 1]; G = graph(s,t,weights); plot(G,'EdgeLabel',G.Edges.Weight)
求节点 3 和 8 之间的最短路径,并指定两个输出以同时返回该路径的长度。
[P,d] = shortestpath(G,3,8)
P = 3 9 5 7 8 d = 4
由于图中心的边具有较大权重,节点 3 和 8 之间的最短路径围绕边权重最小的图边界。此路径的总长度为 4。
shortestpathtree——从节点的最短路径树
语法及说明
TR = shortestpathtree(G,s) %返回有向图 TR,其中包含从源节点 s 到图中所有其他节点的最短路径树。如果图进行了加权(即 G.Edges 包含变量 Weight),则这些权重用作沿图中各边的距离。否则,所有边距离都视为 1。 TR = shortestpathtree(G,s,t) % 计算多个源或目标节点之间的最短路径树: %s 可以是单个源节点,t 可以指定多个目标节点。 %s 可以指定多个源节点,t 可以指定单个目标节点 TR = shortestpathtree(___,Name,Value) %使用由一个或多个名称-值对组参数指定的其他选项,这些选项使用上述语法中的任意输入参数组合。例如,shortestpathtree(G,s,'OutputForm','vector') 返回用于描述最短路径树的数值向量。 [TR,D] = shortestpathtree(___) %还返回树中各节点之间的最短路径距离。 [TR,D,E] = shortestpathtree(___) % 还返回逻辑向量 E,指示图中的每条边是否在 TR 中。
示例
从指定源节点的最短路径:
求从一个源节点到图中每个其他可达节点的最短路径,并绘制结果。
创建一个有向图。
s = [1 1 2 3 3 4 4 6 6 7 8 7 5]; t = [2 3 4 4 5 5 6 1 8 1 3 2 8]; G = digraph(s,t)
计算从节点 1 到图中每个其他可达节点的最短路径。然后,在图上绘制所得到的树。
TR = shortestpathtree(G,1); p = plot(G); highlight(p,TR,'EdgeColor','r')
G = digraph with properties: Edges: [13x1 table] Nodes: [8x0 table]
由于不存在从节点 1 到节点 7 的路径,节点 7 从树中断开连接。
到指定目标节点的最短路径:
求从图中每个节点到一个目标节点的最短路径,并绘制结果。
创建并绘制一个图。
s = [1 1 1 1 1 1 1 2 2 7 7 7 7 9 9 3 3 1 6 4 8 10 6 8 4 5]; t = [2 3 4 5 6 8 7 6 7 5 6 8 9 6 8 6 10 10 10 10 10 11 11 11 8 8]; G = graph(s,t); x = [0 0.5 -0.5 -0.5 0.5 0 1.5 0 2 -1.5 -2]; y = [0 0.5 0.5 -0.5 -0.5 2 0 -2 0 0 0]; plot(G,'XData',x,'YData',y)
查找从图中每个节点到节点 10 的最短路径。绘制所得到的树。
TR = shortestpathtree(G,'all',10); plot(TR)
distances——所有节点对组的最短路径距离
语法及说明
d = distances(G) % 返回矩阵 d,其中 d(i,j) 是节点 i 和节点 j 之间的最短路径的长度。如果图进行了加权(即 G.Edges 包含变量 Weight),则这些权重用作沿图中各边的距离。否则,所有边距离都视为 1。 d = distances(G,s) %将源节点限制为由 s 定义的节点,这样 d(i,j) 就是从节点 s(i) 到节点 j 的距离。 d = distances(G,s,t) %还将目标节点限制为由 t 定义的节点,这样 d(i,j) 就是从节点 s(i) 到节点 t(j) 的距离。 d = distances(___,'Method',algorithm) %可以使用上述语法中的任何输入参数指定在计算最短路径时使用的算法。
示例
所有节点对组的最短路径距离:
创建并绘制一个图。
s = [1 1 1 2 5 5 5 8 9]; t = [2 3 4 5 6 7 8 9 10]; G = graph(s,t); plot(G)
计算图中所有节点对组之间的最短路径距离。由于图边没有权重,所有边距离都视为 1。
d = distances(G)
d = 0 1 1 1 2 3 3 3 4 5 1 0 2 2 1 2 2 2 3 4 1 2 0 2 3 4 4 4 5 6 1 2 2 0 3 4 4 4 5 6 2 1 3 3 0 1 1 1 2 3 3 2 4 4 1 0 2 2 3 4 3 2 4 4 1 2 0 2 3 4 3 2 4 4 1 2 2 0 1 2 4 3 5 5 2 3 3 1 0 1 5 4 6 6 3 4 4 2 1 0
d
是对称的,因为 G
为无向图。通常,d(i,j)
是节点 i
和节点 j
之间的最短路径长度,对于无向图,它等于 d(j,i)
。
例如,求节点 1 和节点 10 之间的最短路径长度。
d(1,10)
ans = 5
从指定源的最短路径距离:
创建并绘制一个图。
s = [1 1 1 1 2 2 3 4 4 5 6]; t = [2 3 4 5 3 6 6 5 7 7 7]; G = graph(s,t); plot(G)
求从节点 1、节点 2 和节点 3 到图中所有其他节点的最短路径距离。
d = distances(G,[1 2 3])
d = 3×7 0 1 1 1 1 2 2 1 0 1 2 2 1 2 1 1 0 2 2 1 2
使用 d
求从节点 1 到节点 7 的最短路径距离。
d(1,7)
ans = 2
maxflow——图中的最大流
前置知识
最大流:
在最大流情景中,图中的边被视为具有由边权重表示的容量。边的容量是可通过该边的流量。因此,图中两个节点之间的最大流代表基于各连接边的容量可从源节点 s
传递到目标节点 t
的最大流量。
最小割:
最小割指将有向图节点分为两个组 - cs
和 ct
,且连接 cs
和 ct
的所有边的权重之和(割的权重)最小。最小割的权重等于最大流值 mf
。
cs
和 ct
中的条目指示 G
的分别与节点 s
和 t
相关联的节点。cs
和 ct
满足 numel(cs) + numel(ct) = numnodes(G)
。
语法及说明
mf = maxflow(G,s,t) %返回节点 s 和 t 之间的最大流。如果图 G 未加权(即 G.Edges 不包含变量 Weight),则 maxflow 将所有图边的权重视为 1。 mf = maxflow(G,s,t,algorithm) % 指定要使用的最大流算法。此语法仅在 G 为有向图时可用。 [mf,GF] = maxflow(___) %还使用上述语法中的任何输入参数返回有向图对象 GF。GF 仅使用 G 中具有非零流值的边构造。 [mf,GF,cs,ct] = maxflow(___) %还返回源和目标节点 ID cs 和 ct,表示与最大流相关联的最小割。
示例
图中的最大流:
创建并绘制一个加权图。加权边表示流量。
s = [1 1 2 2 3 4 4 4 5 5]; t = [2 3 3 4 5 3 5 6 4 6]; weights = [0.77 0.44 0.67 0.75 0.89 0.90 2 0.76 1 1]; G = digraph(s,t,weights); plot(G,'EdgeLabel',G.Edges.Weight,'Layout','layered');
确定从节点 1 到节点 6 的最大流。
mf = maxflow(G,1,6)
mf = 1.2100
最小割计算:
创建并绘制一个加权图。边权重表示流量。
s = [1 1 2 3 3 4 4 5 5]; t = [2 3 3 2 5 5 6 4 6]; weights = [0.77 0.44 0.67 0.69 0.73 2 0.78 1 1]; G = digraph(s,t,weights); plot(G,'EdgeLabel',G.Edges.Weight,'Layout','layered')
求图的最大流和最小割。
[mf,~,cs,ct] = maxflow(G,1,6)
mf = 0.7300 cs = 3×1 1 2 3 ct = 3×1 4 5 6
以 cs
为源节点、ct
为汇聚节点,绘制最小割。将 cs
节点以红色突出显示,ct
节点以绿色突出显示。请注意,连接这两组节点的边的权重等于最大流。
H = plot(G,'Layout','layered','Sources',cs,'Sinks',ct, ... 'EdgeLabel',G.Edges.Weight); highlight(H,cs,'NodeColor','red') highlight(H,ct,'NodeColor','green')
minspantree——图的最小生成树
前置知识
最小生成树:
对于连通图,生成树是一个子图,其中连接图中的每个节点但不包含任何循环。对于任一给定图,可以有许多生成树。通过为每条边分配权重,不同生成树均被分配一个表示其各边总权重的数字。然后,最小生成树就是各边的总权重最小的生成树。
对于边权重相等的图,所有生成树都是最小生成树,因为遍历 n
个节点需要 n-1
条边。
语法及说明
T = minspantree(G) %返回图 G 的最小生成树 T。 T = minspantree(G,Name,Value) %使用一个或多个名称-值对组参数指定的其他选项。例如,minspantree(G,'Method','sparse') 使用 Kruskal 的算法来计算最小生成树。 [T,pred] = minspantree(___) %还使用上述语法中的任何输入参数返回前趋节点的向量 pred。
示例
立方体图的最小生成树:
使用加权边创建并绘制一个立方体图。
s = [1 1 1 2 5 3 6 4 7 8 8 8]; t = [2 3 4 5 3 6 4 7 2 6 7 5]; weights = [100 10 10 10 10 20 10 30 50 10 70 10]; G = graph(s,t,weights); p = plot(G,'EdgeLabel',G.Edges.Weight);
计算并在图上方绘制图的最小生成树。T
包含的节点与 G
相同,但包含的边仅为后者的子集。
[T,pred] = minspantree(G); highlight(p,T)
始于指定根节点的最小生成森林:
创建并绘制一个包含多个分量的图。
s = {'a' 'a' 'a' 'b' 'b' 'c' 'e' 'e' 'f' 'f' 'f' 'f' 'g' 'g'}; t = {'b' 'c' 'd' 'c' 'd' 'd' 'f' 'g' 'g' 'h' 'i' 'j' 'i' 'j'}; G = graph(s,t); p = plot(G,'Layout','layered');
找出图的最小生成森林,从节点 i
开始。在绘图中突出显示生成的森林。图节点名称显示在最小生成树图中。
[T,pred] = minspantree(G,'Type','forest','Root',findnode(G,'i')); highlight(p,T)
使用前趋节点向量 pred
创建有向最小生成森林。此树中的所有边都从每个分量中的根节点(节点 i
和 a
)向外发出。
rootedTree = digraph(pred(pred~=0),find(pred~=0),[],G.Nodes.Name); plot(rootedTree)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步