我有一个Nx2矩阵(在本例中为6X2),如下所示:
5 4
8 6
9 8
10 9
15 14
16 15
我想以下列方式对它们进行分组:
*(5,4)是第1组。用剩余的行检查它。由于5或4都没有出现在剩余的行中,因此可以保持不变。
*(8,6)是下一组。然而在第3行中,8再次出现为(9,8)。所以它连接到第二组,即第二组变为(8,6,9,8)。
*下一个(10,9)。但是9属于第2组,也有10个。所以第二组现在是(8,6,9,8,10,9)。
*下一个(15,14)被看到。到目前为止还没有出现或重复过。所以它成为第3组,即(15,14)。
*最后,看到了(16,15)。但是由于第3组中已经重复了15次,所以该组现在更新为(15,14,16,15)。
最后,MATLAB中的unique
命令可用于删除组中的冗余元素。
我希望最终输出为No of groups:
5 4
8 6 9 10
15 14 16
注意:行方式组中元素的顺序并不重要,因为(5,4)或(4,5)是相同的。我猜也是,最后的输出可能附加零,以使其成为相同尺寸的矩阵,即
5 4 0 0
8 6 9 10
15 14 16 0
请帮助。谢谢。
答案 0 :(得分:1)
这让我想起了一般的集群化问题。 Cuthill-McKee算法正是您搜索的算法,尽管它通常以不同的术语表达。好消息是Matlab在symrcm
函数中实现了它。
这是一段与你的例子一起使用的代码。请注意,它非常强大,并且还能够处理更复杂的数据集:
% --- Definition
D = [5 4 ; 8 6 ; 9 8 ; 10 9 ; 15 14 ; 16 15];
N = max(D(:));
U = unique(D(:));
% --- Tansformation to adjacency matrix
A = sparse(N,N);
% Diagonal element
for i = 1:numel(U)
A(U(i),U(i)) = 1;
end
% Adjacency links
for i = 1:size(D,1)
A(D(i,1),D(i,2)) = 1;
A(D(i,2),D(i,1)) = 1;
end
% --- Cuthill Mc-Kee algorithm
r = symrcm(A);
% --- Find the clusters
% Preparation
B = (A(r,r)^N)>0;
i = 1;
C = {};
% Find clusters iteratively
while i<=N
if ~any(B(:,i))
i = i+1;
else
I = find(B(:,i));
i = max(I)+1;
C{end+1} = r(I);
end
end
% --- Display
for i = 1:numel(C)
disp(C{i})
end
和输出:
5 4
10 9 8 6
16 15 14
最佳,
答案 1 :(得分:1)
所以,我觉得应该有一种方法可以使用基于树的算法或不相交集/联合查找类型方法来实现。但是对于一个肮脏的第一种方法,可能不是那么有效,我编写了以下内容:
A = [5 4
8 6
9 8
10 9
15 14
16 15
8 8
3 4
3 1
];
B = mat2cell(A,ones(size(A,1),1),2);
iter = 1;
while(true)
if (iter > size(B,1))
break
end
y = B{iter};
C = cat(1,false(iter,1),cellfun(@(x) any(sum(bsxfun(@eq,x,y'))),B(iter+1:end)));
if any(C)
B{iter} = (cat(2,B{iter}, B{C}));
% or put you can start shortening them here, by calling unique() already:
%B{iter} = unique(cat(2,B{iter}, B{C}));
B(C) = [];
else
iter = iter+1;
end
end
B = cellfun(@unique,B,'uni',false);
B{:}
效果很好。我不知道这是否适合你想要的东西,但快速编码很有趣。感谢有趣的问题。