我有一个matrix
(4096x4),其中包含从8个数字池中取得的四个值的所有可能组合。
...
3 63 39 3
3 63 39 19
3 63 39 23
3 63 39 39
...
我只对包含四个唯一值的矩阵行感兴趣。例如,在上一节中,应删除第一行和最后一行,为我们提供 -
...
3 63 39 19
3 63 39 23
...
我当前的解决方案感觉不够优雅 - 基本上,我遍历每一行并将其添加到result
矩阵中,如果它包含四个唯一值:
result = [];
for row = 1:size(matrix,1)
if length(unique(matrix(row,:)))==4
result = cat(1,result,matrix(row,:));
end
end
有更好的方法吗?
答案 0 :(得分:3)
sortedmatrix = sort(matrix,2)
result = matrix(all(diff(sortedmatrix,[],2)~=0,2),:)
将其分解为几个步骤以便解释
sort
执行此任务。diff
是用于此目的的工具。at least one zero
的任何行,表示具有重复行的行。换句话说,no zero
的任何行都表示没有重复行的行,我们希望在输出中找到这些行。 all
让我们完成了这项工作,以获得这种匹配的逻辑数组。matrix indexing
从matrix
中选择这些行以获得预期的输出。这可能是基于实验 bsxfun
的方法,因为它不会有内存效率 -
matches = bsxfun(@eq,matrix,permute(matrix,[1 3 2]))
result = matrix(all(all(sum(matches,2)==1,2),3),:)
将其分解为几个步骤以便解释
bsxfun
查找每个元素与同一行中所有其他元素的匹配逻辑数组。dim-2
个匹配项中对这些匹配项求和,然后在all ones
和dim-2
中找到dim-3
个元素,使我们获得与之前基于diff + sort
的索引数组相同的索引数组方法matrix
中选择适当的行作为最终输出。从MATLAB文件交换的帖子combinator
获取帮助
假设您在名为8
的数组中拥有pool8
值池,您可以直接获取result
-
result = pool8(combinator(8,4,'p'))
combinator(8,4,'p')
基本上为我们提供8
元素的索引4
一次而不重复。我们使用这些索引来索引pool
并获得预期的输出。
答案 1 :(得分:1)
对于有限数量的池,这将起作用。 Create是唯一数组,遍历池中的每个数字,计算它在行中出现的次数,如果找到一个或零个数字,则仅将IsUnique
保持为1。接下来,找到IsUnique
仍为1的位置,提取这些行并完成。
matrix = [3,63,39,3;3,63,39,19;3,63,39,23;3,63,39,39;3,63,39,39;3,63,39,39];
IsUnique = ones(size(matrix,1),1);
pool = [3,63,39,19,23,6,7,8];
for NumberInPool = 1:8
Temp = sum((matrix == pool(NumberInPool))')';
IsUnique = IsUnique .* (Temp<2);
end
UniquePositions = find(IsUnique==1);
result = matrix(UniquePositions,:)