我有一个矩阵,其中每一行都是两个数字的组合,例如A = [1 2; 2 5; 3 4; 4 6; 5 6]
A
,以便对于每一行,第一个元素总是小于第二个元素。
我需要从A
返回链接元素列表(在上面的例子中,链接元素列表是1 2 5 6
和3 4 6
)。这些列表基本上是通过考虑一行来构建的,而检查是最后一个数字是另一行的第一个数字。你有什么建议怎么做吗?
答案 0 :(得分:4)
如果我正确地得到了问题,假设A
为输入数组,则可以使用bsxfun
-
mask = bsxfun(@eq,A(:,1),A(:,2).');
out = unique(A(any(mask,1).' | any(mask,2),:))
示例运行 -
>> A
A =
1 2
3 4
2 5
5 6
>> mask = bsxfun(@eq,A(:,1),A(:,2).');
>> unique(A(any(mask,1).' | any(mask,2),:))
ans =
1
2
5
6
您也可以使用ismember
,就像这样 -
out = unique(A(ismember(A(:,1),A(:,2)) | ismember(A(:,2),A(:,1)),:))
第三个选项是使用intersect
来解决它,就像这样 -
[~,idx1,idx2] = intersect(A(:,1),A(:,2));
out = unique(A([idx1,idx2],:))
答案 1 :(得分:2)
以下似乎有效。它构建一个矩阵(B
),告诉哪些元素是连接的(通过1步)。然后它扩展该矩阵(C
)以包括0步,1步,......,(n-1
)步骤连接,其中n
是节点数。 / p>
从该矩阵中,获得连接元素组(R
)。最后,只保留“最大”组(即那些不包含在其他组中的组)。
A = [1 2; 3 4; 2 5; 4 6; 5 6]; %// data
n = max(A(:));
B = full(sparse(A(:,1), A(:,2), 1, n, n )); %// matrix of 1-step connections
C = eye(n) | B; %// initiallize with 0-step and 1-step connections
for k = 1:n-1
C = C | C*B; %// add k-step connections, up to k=n-1
end
[ii, jj] = find(C);
R = accumarray(ii, jj, [], @(x) {sort(x).'}); %'// all groups (maximal or not)
[xx, yy] = ndgrid(1:n);
C = cellfun(@(x,y) all(ismember(x, y)), R(xx), R(yy) ); %// group included in another?
result = R(all(~C | eye(n), 2)); %// keep only groups that are not included in others
这给出了
>> result{:}
ans =
1 2 5 6
ans =
3 4 6