查找满足一些约束的无序行对的索引

时间:2018-12-03 13:27:10

标签: arrays matlab filter

我在维度为U1的Matlab中有两个向量U29x1,都列出了从19的整数。

clear
U1=(1:1:9).';
U2=U1;

然后我通过获取U(9*9)x1的笛卡尔积来构造大小为U1的向量U2

[ca, cb] = ndgrid(U1, U2);
U=[ca(:) cb(:)];

U的结构基本上是

  U=[1 1;
     2 1;
     ...;
     9 1;
     ---;
     1 2;
     ...
     9 2;
     ---;
     ...
     9 9]

现在,我希望您的帮助来构造一个向量ind,该向量列出U的无序行对的行索引,使得:

(*) i~=kj~=l,其中[i,j][k,l]是来自U的两行

我编写了一段代码,该代码可以实现我想要的功能,但由于下面的步骤1),对我来说似乎效率不高。你能帮助改善吗?

步骤1)从U

中获取 ALL 无序行对的行索引
ind_temp=nchoosek([1:1:9^2], 2); %3240x2

第2步)从ind_temp中删除不满足(*)

的行索引
ind=cell(size(ind_temp,1),1);
for p=1:size(ind,1)
    if U(ind_temp(p,1),1)~=U(ind_temp(p,2),1) && ...
       U(ind_temp(p,1),2)~=U(ind_temp(p,2),2)
       ind{p}=ind_temp(p,:);
    end
end
ind=vertcat(ind{:});

2 个答案:

答案 0 :(得分:0)

这里没有必要使用for循环。或者,您可以计算U中所有行之间的汉明距离。汉明距离是不同坐标的百分比,因此,如果该行中的两个值都不匹配,则汉明距离将等于1。

d = squareform(pdist(U,'hamming')); % Hamming distance between all rows
d = triu(d); % Set all values below the diagonal to 0, so we don't get [1 2] and [2 1] in ind.
[q,w] = find(d==1); % q and w will be row/column of all d==1 values.
ind = [q w]; % Assemble ind
ind = sortrows(ind); % Only necessary to sort rows if you want results exactly matching your example

答案 1 :(得分:0)

向量化此代码非常简单(向量化通常意味着删除循环)。例如,U(ind_temp(:,1),:)是一个矩阵,其对来自U,但根据ind_temp第一栏中的值进行重复和排序。我们可以在第二列中重复该操作,然后直接比较所有对:

I = all(U(ind_temp(:,1),:) ~= U(ind_temp(:,2),:),2);

现在I是一个逻辑数组,其长度与ind_temp(3240x1)相同,指示ind_temp中的哪个对满足约束。我们可以使用它来索引到ind_temp中,如下所示:

ind = ind_temp(I,:);

在Octave上,此矢量化代码比原始代码快3个数量级。在MATLAB上,差异不会那么明显,但仍然应该明显更快。