Генерация всех комбинаций с повторением с помощью MATLAB
как создать все в K-сочетаний с повторениями данного набора (также называется к-multicombinations или multisubsets) использование MATLAB?
это похоже на декартово произведение, но две строки, которые отличаются только их сортировкой, следует считать одинаковыми (например, векторы [1,1,2]=~=[1,2,1]
считаются одинаковыми), поэтому генерируют декартово произведение, а затем применяют unique(sort(cartesianProduct,2),'rows')
должно дать то же самое результаты.
пример:
Зов nmultichoosek(1:n,k)
должен генерировать следующую матрицу:
nmultichoosek(1:3,3)
ans =
1 1 1
1 1 2
1 1 3
1 2 2
1 2 3
1 3 3
2 2 2
2 2 3
2 3 3
3 3 3
3 ответов
мы можем использовать биекцию, упомянутую в статья в Википедии, который отображает сочетания без повторения типа n+k-1 choose k
to k
-multicombinations в размере n
. Мы генерируем комбинации без повторения и сопоставляем их с помощью bsxfun(@minus, nchoosek(1:n+k-1,k), 0:k-1);
. Это приводит к следующей функции:
function combs = nmultichoosek(values, k)
%// Return number of multisubsets or actual multisubsets.
if numel(values)==1
n = values;
combs = nchoosek(n+k-1,k);
else
n = numel(values);
combs = bsxfun(@minus, nchoosek(1:n+k-1,k), 0:k-1);
combs = reshape(values(combs),[],k);
end
подход грубой силы: создайте все кортежи, а затем сохраните только те, которые отсортированы. Не подходит для больших значений n
или k
.
values = 1:3; %// data
k = 3; %// data
n = numel(values); %// number of values
combs = values(dec2base(0:n^k-1,n)-'0'+1); %// generate all tuples
combs = combs(all(diff(combs.')>=0),:); %'// keep only those that are sorted
Это, вероятно, еще более жестокий (интенсивный для памяти) метод, чем предыдущие сообщения, но аккуратный читаемый однострочный:
combs = unique(sort(nchoosek(repmat(values,1,k),k),2),'rows');