Сортировка и рандомизация матрицы в соответствии с определенным ограничением - PullRequest
1 голос
/ 29 февраля 2012

У меня есть матрица 32 х 3 следующим образом:

A =

[1 1 1;

1 1 2;

1 1 3;

1 1 4;

1 1 5;

1 1 6;

1 1 7;

1 1 8;

1 2 1;

1 2 2;

1 2 3;

1 2 4;

1 2 5;

1 2 6;

1 2 7;

1 2 8;

2 1 1;

2 1 2;

2 1 3;

2 1 4;

2 1 5;

2 1 6;

2 1 7;

2 1 8;

2 2 1;

2 2 2;

2 2 3;

2 2 4;

2 2 5;

2 2 6;

2 2 7;

2 2 8]

Что мне нужно сделать, так это рандомизировать порядок строк при сохранении значений строк вместе, однако это необходимо ограничить так, чтобы для A (:, 4) каждые 8 ​​строк содержали только числа 1 - 8 Например, у вас может быть что-то вроде:

A (1: 8, :) =

[1 2 4;

1 1 5;

2 1 6;

1 1 8;

2 2 1;

2 1 2;

2 1 7;

1 1 3]

Наличие 1 и 2 в первых двух столбцах должно быть случайным, 1 - 8 должно быть рандомизировано для каждых 8 значений третьего столбца. Первоначально я пытался использовать функцию randswap в цикле с добавленным ограничением, но это привело только к бесконечному циклу. Также важно, чтобы строки оставались вместе, так как 1 и 2 в первых двух столбцах должны появляться рядом с последним столбцом равное количество раз. Кто-то предложил следующее, но это не совсем работает ..

  m = size(A,1);

  n = 1:8;

  out = 1;

  i2 = 1;

  while ~all(ismember(1:8,out)) && i2 < 100

   i1 = randperm(m);

   out = A(i1(n),:);

   i2 = i2 + 1;

  end

1 Ответ

1 голос
/ 29 февраля 2012

Если все, что вам нужно, это получить один набор из 8 строк из A, вы можете построить результат следующим образом:

out = [randi([1,2],[8,2]),randperm(8)']

out =
     2     1     5
     2     1     2
     2     1     1
     1     2     7
     2     2     6
     1     1     8
     2     2     3
     1     1     4

Если вам нужно рандомизировать все A, вы можете сделать следующее:

%# calculate index for the 1's and 2's
r = rand(8,4);
[~,idx12] = sort(r,2);

%# calculate index for the 1's through 8's
[~,idx8] = sort(r,1);

%# use idx8 to shuffle idx12
idx8into12 = bsxfun(@plus,idx8,[0 8 16 24]);

%# now we can construct the output matrix
B = [1 1;1 2;2 1;2 2];
out = [B(idx12(idx8into12),:),idx8(:)];

out =
     1     1     7
     1     2     3
     1     2     1
     2     1     8
     2     1     5
     2     2     4
     2     2     2
     2     1     6
     1     1     3
     1     2     7
     1     1     1
     1     2     8
     1     2     4
     1     1     5
     2     2     6
     2     1     2
     1     1     8
     2     1     7
     1     2     5
     2     1     1
     1     2     6
     2     1     3
     1     1     2
     1     1     4
     2     1     4
     2     2     7
     2     2     8
     2     2     3
     1     2     2
     1     1     6
     2     2     5
     2     2     1

Если вы сделаете unique(out,'rows'), вы увидите, что действительно есть 32 уникальных строки. Каждые 8 ​​строк в out имеют номера от 1 до 8 в третьем столбце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...