У меня есть следующий вектор 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
спасибо, с уважением...
Matlab перемешивает элементы вектора с одной и той же последовательностью одного и того же числа
Ответы (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
Это работает следующим образом:
- Присвоить каждому элементу
a
уникальные метки в зависимости от их значений (это векторlab
); - Применить случайную биекцию значений
lab
к самим себе (случайная биекция представлена r
; результат ее применения равенr(lab)
); - Отсортировать
r(lab)
и получить индексы сортировки (этоind
); - Примените эти индексы к
a
.
person
Luis Mendo
schedule
30.09.2016
3 3 5 5 3 3 4 4
? - person Suever   schedule 30.09.2016