【问题标题】:Find indices of unordered pairs of rows satisfying some constraints查找满足某些约束的无序行对的索引
【发布时间】:2018-12-03 13:27:10
【问题描述】:

我在 Matlab 中有两个向量 U1U2,维度为 9x1,它们都列出了从 19 的整数。

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

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

[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{:});

【问题讨论】:

    标签: arrays matlab filter


    【解决方案1】:

    这里没有必要使用 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
    

    【讨论】:

      【解决方案2】:

      对这段代码进行向量化是相当直接的(向量化通常意味着删除循环)。例如,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 上,差异不会那么显着,但仍会明显更快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 2018-04-11
        相关资源
        最近更新 更多