Если вы пытаетесь воспроизвести randsample
(или randperm
), почему бы просто не воспроизвести алгоритм, который использует MATLAB? (Насколько мы можем судить ...)
Это тасовка Фишера-Йейтса . Если у вас есть вектор v
, каждая итерация выбирает случайный, ранее не использованный элемент и помещает его в конец невыбранных элементов. Если вы выполните k
итераций, последними k
элементами списка будут ваши случайные выборки. Если k
равно количеству элементов в v
, вы перетасовали весь массив.
function sample = fisher_yates_sample(v, k)
% Select k random elements without replacement from vector v
% if k == numel(v), this is simply a fisher-yates shuffle
for n = 0:k-1
randnum = randi(numel(v)-n); % choose from unused values
% swap elements v(end-n) and v(randnum)
v([end-n, randnum]) = v([randnum, end-n]);
end
sample = v(end-k+1:end);
end
В отличие от версии MATLAB, мой требует ввода вектора, поэтому для получения 6 случайных значений в диапазоне 1:12
вы бы вызвали функцию следующим образом:
>> fisher_yates_sample(1:12,6)
ans =
5 11 6 10 8 4