我有一个带边和点的网络。 FID
显示由Start_Point
和End_Point
创建的每条边的ID号。例如,边3
位于网络中2
和3
的两个点之间。
FID Start_Point End_Point
1 1 2
2 1 4
3 2 3
4 2 4
我想创建这些点的 4 -by- 4 矩阵。如果2点之间存在边缘,则值为1
,否则为inf
:
[inf, 1, inf, 1;
1, inf, 1, 1;
inf, 1, inf, inf;
1, 1, inf, inf]
如何在MATLAB中创建这样的矩阵?
答案 0 :(得分:3)
您可以将其转换为稀疏矩阵,然后使用完整命令获取邻接矩阵。
edges= [1 2;
3 4;
3 1
2 3];
n=size(edges,1);
% create sparse matrix with given edges and their reverse direction
A = sparse([edges(:,1); edges(:,2)],[edges(:,2); edges(:,1)],[ones(n,1); ones(n,1)]);
% create adjacency matrix
B=full(A);
% set zeros to inf
B(B==0)=inf;
这就是结果:
A =
(2,1) 1
(3,1) 1
(1,2) 1
(3,2) 1
(1,3) 1
(2,3) 1
(4,3) 1
(3,4) 1
>> B
B =
Inf 1 1 Inf
1 Inf 1 Inf
1 1 Inf 1
Inf Inf 1 Inf
修改: sparse命令创建一个稀疏矩阵,其中包含其元素的寻址值。该命令的一个原型如下:
A=sparse(rows,cols,values);
例如A=sparse([1;2],[1,3],[10,5])
是A(1,1)=10
和A(2,3)=5
以及其他元素为零的矩阵:
A=sparse([1;2],[1,3],[10,5]);
>> full(A)
ans =
10 0 0
0 0 5
在您的情况下,您必须向稀疏矩阵(对称)添加两个方向,并且所有值都是一个。所以你需要构造稀疏矩阵:
A = sparse([edges(:,1); edges(:,2)],[edges(:,2); edges(:,1)],[ones(n,1); ones(n,1)]);
完整命令将稀疏矩阵转换为密集矩阵。
答案 1 :(得分:2)
所以你基本上想要从边缘的邻接列表中创建一个邻接矩阵?您的边数(即您的FID
列)无关紧要,因此我假设您的输入数据格式为
edges = [1 2
1 4
2 3
2 4]
现在第一列边是你的邻接矩阵的行,第二列是列(反之亦然,因为你的矩阵是对称的,所以它并不重要)
最简单的解决方案是使用线性索引,您可以通过sub2ind
函数获得:
adj = inf(size(edges,2));
idx = sub2ind(size(adj),edges(:,1), edges(:,2))
adj(idx) = 1;
我怀疑你的edges
矩阵已经是对称的,但如果它不是,那么只需使用
edges_sym = [edges; fliplr(edges)]
而不是edges
答案 2 :(得分:1)
您可以使用accumarray
:
edges1 = accumarray([startpoint endpoint]),1);
edges2 = edges1.'; % transpose your matrix, to obtain both edges
edges = edges1+edges2;
edges(edges==0)=inf;
accumarray
使用公共索引收集所有点,在这些索引上粘贴值1
。 edges1
是edges2
的转置,因此转置,然后将两者加在一起。找到矩阵为0
的所有索引,然后使用inf
填充这些值。
替代:
edges= [1 2;
3 4;
3 1
2 3];
matrix = accumarray([edges;fliplr(edges)],1,[],[],inf);
fliplr
从左到右翻转矩阵,以获得所有所需的索引组合。然后使用accumarray
在1
指定的所有位置设置edges
,并将inf
放在其他位置。
如果您确定矩阵是对称的,请不要使用fliplr
,如果您确定矩阵是非对称的,请使用fliplr
,如果您不确定使用此:
matrix = accumarray([edges;fliplr(edges)],1,[],@mean,inf);
其中@mean
确保将双项设置为1。对于加权边,请执行以下操作:其中weights
是包含权重的Nx1
数组,N
是边数。
matrix = accumarray([edges;fliplr(edges)],weights,[],@mean,inf);