2011-02-03 251 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