Matlab перемешивает элементы вектора с одной и той же последовательностью одного и того же числа

У меня есть следующий вектор a = 3 3 5 5 20 20 20 4 4 4 2 2 2 10 10 10 6 6 1 1 1 Кто-нибудь знает, как перетасовать этот вектор с одинаковыми элементами, которые никогда не будут отдельными? что-то вроде ниже a = 10 10 10 5 5 4 4 4 20 20 20 1 1 1 3 3 2 2 2 6 6 спасибо, с уважением...


person 8727    schedule 30.09.2016    source источник
comment
Гарантируется ли, что группы всегда будут уникальными, чтобы у вас не было: 3 3 5 5 3 3 4 4?   -  person Suever    schedule 30.09.2016
comment
да, у меня есть эта матрица сначала a = [3 2;5 2;20 3;4 3;2 3;10 3;6 2;1 3] я что-то сделал, и моя матрица стала: a = [3 2;3 2 ;5 2;5 2;20 3;20 3;20 3;4 3;4 3;4 3;2 3;2 3;2 3;10 3;10 3;10 3;6 2;6 2;1 3;1 3;1 3] и теперь мне нужно рандомизировать значение первой строки...   -  person 8727    schedule 01.10.2016


Ответы (3)


Вы можете использовать unique в сочетании с accumarray для создания массива ячеек, где каждая группа значений помещается в отдельный элемент ячейки. Затем вы можете перетасовать эти элементы и объединить их в массив.

% Put each group into a separate cell of a cell array
[~, ~, ind] = unique(a);
C = accumarray(ind(:), a(:), [], @(x){x});

% Shuffle it
shuffled = C(randperm(numel(C)));

% Now make it back into a vector
out = cat(1, shuffled{:}).';

%   20 20 20  1  1  1  3  3 10 10 10  5  5  4  4  4  6  6  2  2  2

Другой вариант — получить значения с помощью unique, а затем вычислить число, которое встречается в каждом из них. Затем вы можете перемешать значения и использовать repelem, чтобы расширить результат.

u = unique(a);
counts = histc(a, u);

% Shuffle the values
inds = randperm(numel(u));

% Now expand out the array
out = repelem(u(inds), counts(inds));
person Suever    schedule 30.09.2016

Очень похожий ответ на @Suever, с использованием цикла и логической матрицы, а не ячеек.

a = [3 3 5 5 20 20 20 4 4 4 2 2 2 10 10 10 6 6 1 1 1];

vals = unique(a); %find unique values
vals = vals(randperm(length(vals))); %shuffle vals matrix

aout = []; %initialize output matrix
for ii = 1:length(vals)
     aout = [aout a(a==(vals(ii)))]; %add correct number of each value
end
person Ian Riley    schedule 30.09.2016

Вот еще один подход:

a = [3 3 5 5 20 20 20 4 4 4 2 2 2 10 10 10 6 6 1 1 1];
[~, ~, lab] = unique(a);
r = randperm(max(lab));
[~, ind] = sort(r(lab));
result = a(ind);

Пример результата:

result =
     2  2  2  3  3  5  5 20 20 20  4  4  4 10 10 10  1  1  1  6  6

Это работает следующим образом:

  1. Присвоить каждому элементу a уникальные метки в зависимости от их значений (это вектор lab);
  2. Применить случайную биекцию значений lab к самим себе (случайная биекция представлена ​​r; результат ее применения равен r(lab));
  3. Отсортировать r(lab) и получить индексы сортировки (это ind);
  4. Примените эти индексы к a.
person Luis Mendo    schedule 30.09.2016