我在维度为U1
的Matlab中有两个向量U2
和9x1
,都列出了从1
到9
的整数。
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~=k
和j~=l
,其中[i,j]
,[k,l]
是来自U
的两行
我编写了一段代码,该代码可以实现我想要的功能,但由于下面的步骤1),对我来说似乎效率不高。你能帮助改善吗?
步骤1)从U
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{:});
答案 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上,差异不会那么明显,但仍然应该明显更快。