matlab有一个自带的biography类型,可以直接画图,自带图论各种算法,用起来相当舒服,我是个懒人,虽然学了三四遍图论的各种东西,或者没学会,或者没敲过代码,这次我依然不打算手撸一遍,既然有系统自带的,那就用自带的好了,怕记不住,自己做个笔记写在这里。
首先写一下matlab里如何表示一个图,一般用稀疏矩阵。matlab函数sparse用来生成稀疏矩阵。
比如 R=[1 1 2 4 1 2 3 3 5 7 3 4 5 6 7 8]; C=[2 3 3 3 4 5 5 6 6 6 7 7 8 8 8 7];W=[2 8 6 7 1 1 5 1 3 4 2 9 8 6 3 0];
G=sparse(R,C,W);
这里面R和C分别表示节点,W表示对应两节点之间的边权值。注意sparse会生成一个m*n的double型矩阵,m是R中最大的数字,n是C中最大的数字。如果其值不相同,那么生成的矩阵将不是方阵,而所有的图论算法操作的矩阵都是方阵,所以我在R和C和W的最后添加了8 7 0三个数字,来保证生成方阵。如果R C中出现重复边,会将其权值相加。所以最后在W里写0,不影响边权值。
view(biograph(G,[],'ShowW','ON'));可以查看该图。
其中biography为生成一个biography object
[]中为节点名称 默认为Node1 这种
‘ShowW' ‘ON' 表示显示权值 类似的有'ShowArrows' ‘ON’为显示箭头。
1)最短路算法
graphallshortestpaths(G)返回G的所有最短路径,以矩阵形式返回。
ans =
0 2 8 1 3 6 10 11
Inf 0 6 Inf 1 4 8 9
Inf Inf 0 Inf 5 1 2 5
Inf Inf 7 0 12 8 9 12
Inf Inf Inf Inf 0 3 Inf 8
Inf Inf Inf Inf Inf 0 Inf 6
Inf Inf Inf Inf Inf 4 0 3
Inf Inf Inf Inf Inf Inf Inf 0
其上三角矩阵中ij元素即ij的最短路径。
此时默认为有向图。想求无向图的最短路径,则将稀疏矩阵与其转置相加。
graphallshortestpaths(G+G')
ans =
0 2 7 1 3 6 9 11
2 0 5 3 1 4 7 9
7 5 0 7 4 1 2 5
1 3 7 0 4 7 9 12
3 1 4 4 0 3 6 8
6 4 1 7 3 0 3 6
9 7 2 9 6 3 0 3
11 9 5 12 8 6 3 0
求两点见最短路径为[dist path]=graphshortestpath(G,v1,v2)
其实v1,v2为两点。返回的dist为路径长,path为路径。
比如 [dist path]=graphshortestpath(G,1,8)
得到结果为
dist =
11
path =
1 2 5 8
h=view(biograph(G,[],'showW','on'));
edges=getedgesbynodeid(h,get(h.Nodes(path),'ID'));
set(h.Nodes(path),'color',[1 0 0])
>> set(edges,'LineColor',[1 0 0])
>> set(edges,'LineWidth',1.5)
效果如图
2)最小生成树算法
该算法的函数为 [Tree,pred]=graphminspantree(G);
具体用法可用help命令查找
The output PRED contains the predecessor
nodes of the minimal spanning tree with the root node indicated by a
zero. The root defaults to the first node in the largest connected
component, which requires an extra call to the graphconncomp function.
并没看懂这个返回值干嘛的,好像不重要
注意,此处G需为无向图,即原稀疏矩阵与其转置之和
[ST,pred] = graphminspantree(G)
view(biograph(ST,[],'ShowArrows','off','ShowWeights','on'))
即可得到最小生成树图像
最大流算法
graphmaxflow calculates the maximum flow in a directed graph.
[M,F,K] = graphmaxflow(G,S,D) Calculates the maximum flow of the directed
graph G from node S to node D. G is an n-by-n sparse matrix that
represents a directed graph with non reciprocal edges. Nonzero entries in
G determine the capacity of the edges. M is the maximum flow and F is a
sparse matrix with all the flow values for every edge. F(i,j) is the flow
from node i to j. K is a logical row vector indicating the nodes
connected to S after calculating the minimum between S and D. If several
solutions to the minimum cut problem exist then K is a matrix.
graphmaxflow(...,'METHOD',METHOD) selects the algorithm to use, options
are:
'Edmonds' - Edmonds and Karp algorithm. Implementation is based on
a variation called the "labeling algorithm". Time
complexity is O(n*e^2).
['Goldberg'] - Goldberg algorithm uses the generic method known as
"preflow-push". Time complexity is O(n^2*sqrt(e)).
Notes: (1) n and e are number of nodes and edges respectively. (2) The
algorithm that finds all minimum cuts has a time complexity of O(2^n),
avoid using the third output argument if it is not required.
graphmaxflow(...,'CAPACITY',C) provides custom capacities for the edges.
C is a column vector with one entry for every edge in G, traversed
column-wise.
Example:
% Create a directed graph with 6 nodes
cm = sparse([1 1 2 2 3 3 4 5],[2 3 4 5 4 5 6 6],[2 3 3 1 1 1 2 3],6,6)
% Call the maximum flow algorithm between 1 and 6
[M,F,K] = graphmaxflow(cm,1,6)
% View graph with original flows
h = view(biograph(cm,[],'ShowWeights','on'))
% View graph with actual flows
view(biograph(F,[],'ShowWeights','on'))
% Show in the original graph one solution of the mincut problem
set(h.Nodes(K(1,:)),'Color',[1 0 0])
连例子都这么明确了 我就不多翻译了。生成两张图看看效果吧。
cm =
(1,2) 2
(1,3) 3
(2,4) 3
(3,4) 1
(2,5) 1
(3,5) 1
(4,6) 2
(5,6) 3
M =
4
F =
(1,2) 2
(1,3) 2
(2,4) 1
(3,4) 1
(2,5) 1
(3,5) 1
(4,6) 2
(5,6) 2
K =
1 1 1 1 0 0
1 0 1 0 0 0