2011-02-03 137 views
2

的线性组合我想创建一个矩阵A [4×8],如下所示。生成矩阵

矩阵A总有1作为其对角线。 A11,A22,A33,A44 = 1

该矩阵可被认为是两个半部与第一半是第一4列和第二半是第二4列像下面的内容:

 1 -1 -1 -1 1 0 0 1 
    A = -1 1 -1 0 0 1 0 0 
     -1 -1 1 0 1 0 0 0 
     -1 -1 -1 1 1 1 0 0 

在上半场的每一行可以有两个或三个-1的:

  • ,如果它有两个-1的则是在下半场对应的行应该有一个1
  • 我F所列行有三个-1的矩阵下半年应该有两个1的。

的总体目标是使每行的总和为0。我需要生成像这样的矩阵的所有可能的组合。

这将是更好的,如果有新的组合矩阵在每次迭代创建一个,以便用它后,我可以抛弃它或者存放所有的组合是非常密集的空间。有谁能够帮助我 ?

一个可能的解决方案,我能想到的是产生ROW1,ROW2,ROW3和ROW4的所有可能的组合,创造在每个迭代的矩阵。这看起来可行吗?

+0

你已经试过了什么?你有什么特别的*你与卢布? – 2011-02-03 19:46:03

+0

我无法掌握如何做到这一点的逻辑。我还在想。 :( – 2011-02-03 19:49:50

+0

可能的重复[线性组合的矩阵/向量](http://stackoverflow.com/questions/4890452/linear-combination-of-a-matrix-vector) – 2011-02-03 19:50:00

回答

5

这里是一个可能的解决方案。如果忽略对角线的人的时刻,你可以生成所有可能的模式使用功能KRONREPMATPERMSUNIQUEEYE其他7个值,并ONES

>> rowPatterns = [kron(eye(3)-1,ones(4,1)) ...  %# For 2 out of 3 as -1 
        repmat(eye(4),3,1); ...   %# For 1 out of 4 as 1 
        repmat([-1 -1 -1],6,1) ...  %# For 3 out of 3 as -1 
        unique(perms([1 1 0 0]),'rows')] %# For 2 out of 4 as 1 

rowPatterns = 

    0 -1 -1  1  0  0  0 
    0 -1 -1  0  1  0  0 
    0 -1 -1  0  0  1  0 
    0 -1 -1  0  0  0  1 
    -1  0 -1  1  0  0  0 
    -1  0 -1  0  1  0  0 
    -1  0 -1  0  0  1  0 
    -1  0 -1  0  0  0  1 
    -1 -1  0  1  0  0  0 
    -1 -1  0  0  1  0  0 
    -1 -1  0  0  0  1  0 
    -1 -1  0  0  0  0  1 
    -1 -1 -1  0  0  1  1 
    -1 -1 -1  0  1  0  1 
    -1 -1 -1  0  1  1  0 
    -1 -1 -1  1  0  0  1 
    -1 -1 -1  1  0  1  0 
    -1 -1 -1  1  1  0  0 

注意,这是18可能任何给定行的模式,所以你的矩阵A可以有18^4 = 104,976个可能的行模式(相当多)。可以通过使用功能NDGRIDCAT产生每个可能的4-明智列图案索引和RESHAPE

[indexSets{1:4}] = ndgrid(1:18); 
indexSets = reshape(cat(5,indexSets{:}),[],4); 

而且indexSets将是104976乘4矩阵与含有之间的4个值中的一个组合中的各行1和18,包括在内,用作rowPatterns的索引以生成唯一矩阵A。现在可以循环在每个组的4逐列图案索引和使用该功能TRILTRIUEYE生成矩阵A,和ZEROS

for iPattern = 1:104976 
    A = rowPatterns(indexSets(iPattern,:),:); %# Get the selected row patterns 
    A = [tril(A,-1) zeros(4,1)] + ...   %# Separate the 7-by-4 matrix into 
     [zeros(4,1) triu(A)] + ...    %# lower and upper parts so you 
     [eye(4) zeros(4)];      %# can insert the diagonal ones 
    %# Store A in a variable or perform some computation with it here 
end 
2

下面是另一种解决办法(以最小的循环):

%# generate all possible variation of first/second halves 
z = -[0 1 1; 1 0 1; 1 1 0; 1 1 1]; n = -sum(z,2); 
h1 = { 
    [   ones(4,1) z(:,1:3)] ; 
    [z(:,1:1) ones(4,1) z(:,2:3)] ; 
    [z(:,1:2) ones(4,1) z(:,3:3)] ; 
    [z(:,1:3) ones(4,1)   ] ; 
}; 
h2 = arrayfun(@(i) unique(perms([zeros(1,4-i) ones(1,i)]),'rows'), (1:2)', ... 
    'UniformOutput',false); 

%'# generate all possible variations of complete rows 
rows = cell(4,1); 
for r=1:4 
    rows{r} = cell2mat(arrayfun(... 
     @(i) [ repmat(h1{r}(i,:),size(h2{n(i)-1},1),1) h2{n(i)-1} ], ... 
     (1:size(h1{r},1))', 'UniformOutput',false)); 
end 

%'# generate all possible matrices (pick one row from each to form the matrix) 
sz = cellfun(@(M)1:size(M,1), rows, 'UniformOutput',false); 
[X1 X2 X3 X4] = ndgrid(sz{:}); 
matrices = cat(3, ... 
    rows{1}(X1(:),:), ... 
    rows{2}(X2(:),:), ... 
    rows{3}(X3(:),:), ... 
    rows{4}(X4(:),:)); 
matrices = permute(matrices, [3 2 1]);    %# 4-by-8-by-104976 

%#clear X1 X2 X3 X4 rows h1 h2 sz z n r 

接下来,您可以访问4×8矩阵为:

>> matrices(:,:,500) 
ans = 
    1 -1 -1 -1  0  1  0  1 
    -1  1 -1  0  0  0  1  0 
    0 -1  1 -1  0  0  1  0 
    0 -1 -1  1  0  0  0  1 

我们也可以CONFI rm表示所有矩阵中的所有行总和为零:

>> all(all(sum(matrices,2)==0)) 
ans = 
    1