在MATLAB中生成所有可能的配置

时间:2015-10-20 18:08:01

标签: matlab matrix combinations

我有一个2D矩阵A,它只包含二进制值:

A = [0 0
     0 1
     1 0
     1 1];

我想创建一个函数,在A中生成值的所有可能配置。在这种情况下,单词 configuration 对应于数据行内的任何可能的值组合(即,列对,三元组等)。例如,在上面提供的数据的简单情况下,我希望函数返回:

B = [ A(:,1)==1, ...
      A(:,2)==1, ...
      A(:,1)==0 & A(:,2)==0, ...
      A(:,1)==0 & A(:,2)==1, ...
      A(:,1)==1 & A(:,2)==0, ...
      A(:,1)==1 & A(:,2)==1];

B =

     0     0     1     0     0     0
     0     1     0     1     0     0
     1     0     0     0     1     0
     1     1     0     0     0     1

但是,我希望该函数能够处理任何大小的矩阵。在3列矩阵的情况下,得到的配置数量要大得多:

A = [ 0 0 0
      0 0 1
      0 1 0
      0 1 1
      1 0 0
      1 0 1
      1 1 0
      1 1 1]

B = [A(:,1)==1, ...
     A(:,2)==1, ...
     A(:,3)==1, ...
     A(:,1)==0 & A(:,2)==0, ...
     A(:,1)==0 & A(:,2)==1, ...
     A(:,1)==0 & A(:,3)==0, ...
     A(:,1)==0 & A(:,3)==1, ...
     A(:,1)==1 & A(:,2)==0, ...
     A(:,1)==1 & A(:,2)==1, ...
     A(:,1)==1 & A(:,3)==0, ...
     A(:,1)==1 & A(:,3)==1, ...
     A(:,2)==0 & A(:,3)==0, ...
     A(:,2)==0 & A(:,3)==1, ...
     A(:,2)==1 & A(:,3)==0, ...
     A(:,2)==1 & A(:,3)==1, ...
     A(:,1)==0 & A(:,2)==0 & A(:,3)==0, ...
     A(:,1)==0 & A(:,2)==0 & A(:,3)==1, ...
     A(:,1)==0 & A(:,2)==1 & A(:,3)==0, ...
     A(:,1)==0 & A(:,2)==1 & A(:,3)==1, ...
     A(:,1)==1 & A(:,2)==0 & A(:,3)==0, ...
     A(:,1)==1 & A(:,2)==0 & A(:,3)==1, ...
     A(:,1)==1 & A(:,2)==1 & A(:,3)==0, ...
     A(:,1)==1 & A(:,2)==1 & A(:,3)==1]

这似乎是一个非常具有挑战性的问题,所以我想知道SO社区是否有任何想法!

我目前使用这个[丑陋]功能。它依赖于MATLAB文件交换中的How to use -libjars on aws emr?函数:

function [B] = allconfigs(A)

% some information about A
N = size(A,1);  
D = size(A,2);

% set up storage
B = A==1;

% iterate over levels of dimensionality (pairs, triplets, etc)
%   I==1 can be ignored, as it is equal to A.
%   I==(D-1) can be ignored, as it is an identity matrix of size N

for I = 2:(D-1)

%   get all possible values given dimensionality I
    possiblevalues  = cell(1,I);
    for j = 1:I
        possiblevalues{j} = [0 1];
    end
    possiblevalues = allcomb(possiblevalues{:});
    npossible = size(possiblevalues,1);

%   get all possible combinations of dimensions
    combinations = combnk(1:D,I);
    ncombs = size(combinations,1);

%   check if the data under each dimension combination matches each value possibility
    for J = 1:ncombs
        dimensions = A(:,combinations(J,:));

        for K = 1:npossible
            matches = dimensions == repmat(possiblevalues(K,:),[N,1]);
            matches = all(matches==1,2);

            B = cat(2,B,matches);
        end
    end
end

% if I is the full set of data, the matches are an identity matrix.
B = cat(2,B,eye(N));
return

该函数返回正确的结果(但请注意,它生成的列与我输出的列的顺序不同)。它真是太难看了。有谁知道更优雅的东西?

1 个答案:

答案 0 :(得分:0)

我仍然在理解为B生成的模式时遇到问题,但是可能只有一两行缺失。我想简化的想法是,编码[1,0,nan]中的组合,其中nan表示不关心。例如,A(:,1)==1 & A(:,2)==0将表示为[1,0,nan]

此代码构建了您在B中所需的所有组合。由于我没有完全理解该模式,因此它会生成所有可能的组合:

c=size(A,2);
p={[0,1,nan]};
%1=colum is 1
%0=colum is 0
%nan= don't care
all_rows=allcomb(p{ones(c,1)});
%TODO filter out unwanted rows

现在很简单,将all_rows中的每一行与输入的每个列进行比较。如果两者相等或参考是nan(不关心)

,则为真
B=true(size(A,1),size(all_rows,1));
for ix=1:size(all_rows,1)
    B(:,ix)=all(bsxfun(@(a,b)isnan(a)|eq(a,b),all_rows(ix,:),A),2);
end