[英]Create adjacency matrix from nearest neighbour search. (convert adjacency list to adjacency matrix) - Matlab
我有一个矩阵2000x5
,在第一列中是点号,在2-5列中是4个邻居(如果没有邻居,则为0)。 有没有一种有效的方法可以据此创建邻接矩阵?
1 129 0 65 0
2 130 0 66 85
3 131 169 67 0
4 132 170 68 87
5 133 0 69 81
6 134 0 70 82
7 135 173 71 83
8 136 174 72 84
9 137 161 73 0
10 138 162 74 93
11 139 163 75 0
12 140 164 76 95
13 141 165 77 89
14 142 166 78 90
15 143 167 79 91
16 144 168 80 92
17 145 0 81 65
18 146 0 82 66
....
我找到了以下线程,仅在一个邻居中对其进行了说明,但是我不确定如何在多个邻居中使用它。 Matlab邻接表到邻接矩阵
非常感谢您的帮助。
首先,我将假定邻接表是无向的 。 无论如何,去多个邻居并不是一件容易的事。 首先,需要检测第2列至第5列中每行非零元素的总数。执行此操作后,对于邻接矩阵的行,您将复制点数尽可能多的次数每行非零元素。 函数repelem
非常适合为您执行此操作。 列索引将只是第二列到第五列, 删除所有零元素。 如何做到这一点的方法是首先对矩阵进行转置 ,从而对第二到第五列进行索引,然后使用logical
索引矩阵删除零个条目。 这样做将以列为主的方式展开向量,这就是为什么在执行此操作之前需要转置的原因。 完成此操作后,您可以创建行和列访问索引,以便可以像链接的帖子一样将它们输入到sparse
。
假设您的矩阵存储在A
,您将执行以下操作。 这也假设连接节点的每个权重为1:
% Find total number of non-zero elements per row, skipping first column
non_zero = sum(A(:,2:end) ~= 0, 2);
% Create row indices
rows = repelem(A(:,1), non_zero);
% Create column indices
cols = A(:,2:end).';
cols = cols(cols ~= 0);
% Create adjacency matrix
adj = sparse([rows; cols],[cols; rows], 1);
上面的表示是sparse
。 如果需要完整的数字版本,请使用full
强制转换输出:
adj = full(adj);
如果您有向图而不是无向图,则上述对sparse
副本的调用会复制边,以便您创建往返于每个邻居的链接。 如果您的图形实际上是有向的,则只需要使用行和列索引一次即可,而不必使用上面的代码两次:
% Create adjacency matrix
adj = sparse(rows, cols , 1);
这是一个小的测试用例,向您显示此方法有效。 假设我的邻接列表如下所示:
>> A = [1 0 2 3; 2 4 0 0; 3 0 0 4]
A =
1 0 2 3
2 4 0 0
3 0 0 4
现在,邻接矩阵为:
>> full(adj)
ans =
0 1 1 0
1 0 0 1
1 0 0 1
0 1 1 0
看一下上面的列表以及如何填充矩阵,我们可以验证这是正确的。
repelem
注意repelem
repelem
假定您具有MATLAB R2015a或更高版本。 如果你没有这个,你可以参考此答案由用户Divakar上自定义实现的repelem
:此数组元素的重复副本:运行长度解码的MATLAB
快速简单的技术:
adjMat = zeros(size(A,1));
for ind = 1:size(A,1)
% Flag 1 on each row 'ind' at the indices mentioned in col 2-5
adjMat(ind, nonzeros(A(ind,2:end))) = 1;
end
既然您已经提到使用最近邻居搜索,那么很可能应该完全填充邻接列表以生成无向图,这意味着如果第1行有20个邻居,那么第20行很可能有1个邻居。
但是,从技术上讲,这将产生一个与邻接表完全等效的邻接矩阵,而无需单独假设。
对于邻接表
A = [1 2 3; 2 0 1; 3 1 4; 4 5 3; 5 4 0]
A =
1 2 3
2 0 1
3 1 4
4 5 3
5 4 0
结果是:
adjMat =
0 1 1 0 0
1 0 0 0 0
1 0 0 1 0
0 0 1 0 1
0 0 0 1 0
PS要强制无方向性,您只需在for循环主体中添加另一个语句:
adjMat(nonzeros(A(ind,2:end)),ind) = 1;
这将确保邻接矩阵是对称的,这是无向图的特征。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.