如何查找矩阵的行,其中具有相同且唯一且重复的元素的排序,但不一定是相同的值

时间:2014-02-04 03:24:24

标签: algorithm matlab matrix

我不太确定如何说出这个问题。假设我有以下矩阵:

A=[1 0 0;
   0 0 1;
   0 1 0;
   0 1 1;
   0 1 2;
   3 4 4]

鉴于第1行,我想找到所有行:

  • 第1行中唯一的元素在另一行的同一列中是唯一的,但不一定具有相同的值
  • 如果第1行中存在重复值的元素,则另一行的相同列中存在重复值,但不一定是相同的值

例如,在矩阵A中,如果给出第1行,我想找到第4行和第6行。

5 个答案:

答案 0 :(得分:1)

现在无法测试,但我认为以下内容可行:

A=[1 0 0;
   0 0 1;
   0 1 0;
   0 1 1;
   0 1 2;
   3 4 4];

B = zeros(size(A));

for ii = 1:size(A,1)
  r = A(ii,:);
  B(ii,1) = 1;
  for jj = 2:size(A,2)
    c = find(r(1:jj-1)==r(jj));
    if numel(c) > 0
      B(ii,jj) = B(ii,c);
    else
      B(ii,jj) = B(ii,jj-1)+1;
    end
  end
end

在最后,我们有一个数组B,其中“类似索引具有相似的值”,而您正在寻找的行现在是相同的。

现在你可以做到

[C, ia, ic] = unique(B,'rows','stable');
disp('The answer you want is ');
disp(ia);

您想要的答案将在变量ia中。见http://www.mathworks.com/help/matlab/ref/unique.html#btb0_8v。我并非100%确定您可以在同一个电话中使用rowsstable参数 - 但我认为您可以。

尝试并查看它是否有效 - 如果您需要更多信息,请提出问题。

答案 1 :(得分:0)

这是一个简单的方法

B = NaN(size(A)); %//Preallocation

for row = 1:size(A,1)
    [~,~,B(row,:)] = unique(A(row,:), 'stable');
end

find(ismember(B(2:end,:), B(1,:), 'rows')) + 1

答案 2 :(得分:0)

没有循环的简单解决方案:

row = 1; %// row used as reference
equal = bsxfun(@eq, A, permute(A, [1 3 2]));
equal = reshape(equal,size(A,1),[]); %// linearized signature of each row
result = find(ismember(equal,equal(row,:),'rows')); %// find matching rows
result = setdiff(result,row); %// remove reference row, if needed

关键是计算每一行的“签名”,即其元素的所有组合之间的相等关系。这是通过bsxfun完成的。然后,可以使用ismember轻松找到具有相同签名的行。

答案 3 :(得分:0)

谢谢,Floris。唯一的调用无法正常工作,我认为你也打算在其中使用矩阵B.这是我设法做的,虽然它不是那么干净:

A=[1 0 0 1;
   0 0 1 3;
    0 1 0 1;
    0 1 1 0;
    0 1 2 2;
    3 4 4 3;
    5 9 9 4];

 B = zeros(size(A));

 for ii = 1:size(A,1) 
   r = A(ii,:); 
   B(ii,1) = 1; 
   for jj = 2:size(A,2) 
      c = find(r(1:jj-1)==r(jj)); 
     if numel(c) > 0 
       B(ii,jj) = B(ii,c);
     else
         B(ii,jj) = max(B(ii,:))+1; % need max to generalize to more columns
     end
   end
 end

 match = zeros(size(A,1)-1,size(A,2));
 for i=2:size(A,1)
     for j=1:size(A,2)
         if B(i,j) == B(1,j)
             match(i-1,j)=1;
         end
     end
 end

 index=find(sum(match,2)==size(A,2));

在嵌套循环中,我检查它下面的行中的元素是否与正确的列匹配。如果存在完美匹配,则该行应与行维度相加。

当我针对具体问题推广这个时,我正在处理矩阵填充一组基本大小(A,2)的数字。因此对于base 4和更高版本,else语句中需要max语句以表示不匹配。否则,对于给定行中的某些数字组合,如果没有,则可能会出现元素的重复。

答案 4 :(得分:0)

概述是将每一行减少为“签名”计数元素重复,即你的第1行变为1,2,然后检查是否有相同的签名。