Matlab: come enumerare i possibili modi di formare coppie da un elenco
Supponiamo che io abbia una lista di lunghezza 2k
, diciamo {1,2,...,2k}
. Il numero di modi possibili per raggruppare i 2k
numeri in k
coppie (non ordinate) è n(k) = 1*3* ... *(2k-1)
. Quindi k=2
, abbiamo i seguenti tre modi diversi per formare 2 coppie
(1 2)(3 4)
(1 3)(2 4)
(1 4)(2 3)
Come posso usare Matlab per creare l'elenco sopra, cioè creare una matrice di n(k)*(2k)
tale che ogni riga contenga un modo diverso di raggruppare l'elenco di 2k
numeri in k
coppie.
Risposte
clear
k = 3;
set = 1: 2*k;
p = perms(set); % get all possible permutations
% sort each two column
[~, col] = size(p);
for i = 1: 2: col
p(:, i:i+1) = sort(p(:,i:i+1), 2);
end
p = unique(p, 'rows'); % remove the same row
% sort each row
[row, col] = size(p);
for i = 1: row
temp = reshape(p(i,:), 2, col/2)';
temp = sortrows(temp, 1);
p(i,:) = reshape(temp', 1, col);
end
pairs = unique(p, 'rows'); % remove the same row
pairs =
1 2 3 4 5 6
1 2 3 5 4 6
1 2 3 6 4 5
1 3 2 4 5 6
1 3 2 5 4 6
1 3 2 6 4 5
1 4 2 3 5 6
1 4 2 5 3 6
1 4 2 6 3 5
1 5 2 3 4 6
1 5 2 4 3 6
1 5 2 6 3 4
1 6 2 3 4 5
1 6 2 4 3 5
1 6 2 5 3 4
Poiché qualcuno pensa che la mia precedente risposta non sia utile, pubblico questo.
Ho il seguente metodo di forza bruta per enumerare le coppie. Non particolarmente efficiente. Può anche causare problemi di memoria quando k> 9. In tal caso, posso semplicemente enumerare ma non creare Z e memorizzare il risultato in esso.
function Z = pair2(k)
count = [2*k-1:-2:3];
tcount = prod(count);
Z = zeros(tcount,2*k);
x = [ones(1,k-2) 0];
z = zeros(1,2*k);
for i=1:tcount
for j=k-1:-1:1
if x(j)<count(j)
x(j) = x(j)+1;
break
end
x(j) = 1;
end
y = [1:2*k];
for j=1:k-1
z(2*j-1) = y(1);
z(2*j) = y(x(j)+1);
y([1 x(j)+1]) = [];
end
z(2*k-1:2*k) = y;
Z(i,:) = z;
end