2

我试图解决这个问题,但我无法实现。你能帮我什么吗?

问题

Mat1 | Mat2 | Mat3

 1 2 | 1 3  | 2 6

 1 3 | 2 6  | 2 5

 2 4 | 3 1  | 3 1

 3 1 | 3 5  | 5 2

 4 5 |

当有 3 个矩阵时(例如上面),我想为[column1 column2 matrixnumber]表单中的交集行获取此结果。

上述示例的结果将是

1 3 1

1 3 2

2 6 2

2 6 3

3 1 1

3 1 2

3 1 3

如果结果是形式就可以了[column1 column2 firstmatrix secondmatrix, ...]

1 3 1 2

2 6 2 3

3 1 1 2 3

对于这个问题,我想最多使用一个 for 循环。

你对此有什么想法吗?

4

2 回答 2

4

这是使用 MATLAB 的替代解决方案(似乎比 Gunther 的运行速度更快)intersect

Mat = {[1 2; 1 3; 2 4; 3 1; 4 5],
       [1 3; 2 6; 3 1; 3 5],
       [2 6; 2 5; 3 1; 5 2]};

result = zeros(sum(cellfun(@(x)size(x, 1), Mat)), 3); % # Preallocate memory
k = 1;
for cc = transpose(nchoosek(1:numel(Mat), 2))
    x = intersect(Mat{cc}, 'rows');                   % # Find intersection
    y = ones(size(x, 1), 2) * diag(cc);               % # Generate matrix indices
    result(k:k + numel(y) - 1, :) = [[x; x], y(:)];
    k = k + numel(y);
end

result(all(~result, 2), :) = [];                      % # Discard zero rows
result = unique(result, 'rows');                      % # Discard repeated rows

矩阵result现在应该包含唯一的交集行及其相应的矩阵索引,就像您想要的那样:

result =   
     1     3     1
     1     3     2
     2     6     2
     2     6     3
     3     1     1
     3     1     2
     3     1     3
于 2012-12-30T11:59:01.837 回答
3

如果我理解正确,您有许多对:Mat1, Mat2, Mat3, ... MatN。现在您要查找唯一对,然后找出每个唯一对出现在哪个集合中。

如果你有大量的集合,我建议你开始使用一个单元格数组来保存它们,这会让事情变得更容易:

N = 3; % total number of data sets
Mat = cell(N,1);
Mat{1} = [1 2;
          1 3;
          2 4;
          3 1;
          4 5];
Mat{2} = [1 3;
          2 6;
          3 1;
          3 5];
Mat{3} = [2 6;
          2 5;
          3 1;
          5 2];
% etc.

首先让我们找到唯一的对:

uniq_pairs = unique(cat(1,Mat{:}),'rows');
M = size(uniq_pairs ,1);

然后使用ismember检查哪些集合包含哪些对:

matcontpair = false(M,N); %preallocate
for ii=1:N % unavoidable loop
    matcontpair(:,ii) = ismember(uniq_pairs,Mat{ii},'rows');
end

要将此交集矩阵转换为每对的一组矩阵数,请再次循环遍历它并将最终结果存储在单元数组中(您不能使用数组,因为它们的大小可能不同(仅找到某些对一次,另外两次,另外三次......)

pair_occurence= cell(M,1);
d=1:N;
for jj=1:M
    pair_occurence{jj} = d(matcontpair(jj,:));
end

现在您有一个包含唯一对uniq_pairs的大小矩阵和一个大小Mx2为的出现单元格数组:每个单元格对应于一对并包含存在该对的矩阵列表。pair_occurenceMx1

如果要从列表中删除仅存在于一个矩阵中的对,请使用以下命令:

% find them
lonely_pairs = cellfun(@numel,pair_occurence)<2;
% and destroy them
uniq_pairs(lonely_pairs,:) = [];
pair_occurence(lonely_pairs) = [];
于 2012-12-29T11:30:41.387 回答