Генерация линейной комбинации матрицы - PullRequest
2 голосов
/ 03 февраля 2011

Я хочу создать матрицу A [4x8] следующим образом.

Матрица 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
  • если в какой-либо строке есть три -1, во второй половине матрицы должно быть два 1.

Общая цель состоит в том, чтобы сумма каждой строки составляла 0,Мне нужно сгенерировать все возможные комбинации матрицы следующим образом.

Будет лучше, если матрица с новой комбинацией будет создаваться на каждой итерации, чтобы после ее использования я мог ее отбросить или сохранить все комбинацииочень много местаКто-нибудь может мне помочь ?

одно возможное решение, о котором я мог подумать, - это сгенерировать все возможные комбинации row1, row2, row3 и row4 и создать матрицу в каждой итерации.Это выглядит возможным?

Ответы [ 2 ]

5 голосов
/ 04 февраля 2011

Вот одно из возможных решений.Если на данный момент вы игнорируете диагональные, вы можете сгенерировать все возможные шаблоны для остальных 7 значений, используя функции KRON , REPMAT , PERMS , UNIQUE , EYE и 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 возможных шаблонов строк (совсем немного).Вы можете сгенерировать каждый возможный четырехзначный индекс шаблона строки, используя функции NDGRID , CAT и RESHAPE :

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

AndindexSets будет матрицей 104 976 на 4 с каждой строкой, содержащей одну комбинацию из 4 значений от 1 до 18 включительно, для использования в качестве индексов для rowPatterns для генерации уникальной матрицы A.Теперь вы можете циклически проходить по каждому набору четырехзначных индексов шаблонов строк и генерировать матрицу A, используя функции TRIL , TRIU , EYE и 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 голосов
/ 04 февраля 2011

Вот еще одно решение (с минимальным циклом):

%# 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

Мы также можем подтвердитьстроки во всех матрицах суммируют до нуля:

>> all(all( sum(matrices,2)==0 ))
ans =
     1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...