Matlab: Cách liệt kê các cách có thể tạo thành các cặp từ một danh sách

Jan 20 2021

Giả sử tôi có một danh sách dài 2k, chẳng hạn {1,2,...,2k}. Số cách có thể để nhóm các 2ksố thành kcác cặp (không có thứ tự) là n(k) = 1*3* ... *(2k-1). Vì vậy k=2, chúng ta có ba cách khác nhau sau đây để tạo thành 2 cặp

(1 2)(3 4)

(1 3)(2 4)

(1 4)(2 3)

Làm thế nào tôi có thể sử dụng Matlab để tạo danh sách trên, tức là, tạo một ma trận n(k)*(2k)sao cho mỗi hàng chứa một cách khác nhau để nhóm danh sách các 2ksố thành ktừng cặp.

Trả lời

LucienXhh Jan 20 2021 at 15:37
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

Vì ai đó nghĩ rằng câu trả lời trước đây của tôi không hữu ích, tôi đăng bài này.

RaymondKan Jan 20 2021 at 17:35

Tôi có một cách liệt kê các cặp số một cách thô bạo sau đây. Không đặc biệt hiệu quả. Nó cũng có thể gây ra sự cố bộ nhớ khi k> 9. Trong trường hợp đó, tôi chỉ có thể liệt kê nhưng không tạo Z và lưu trữ kết quả trong đó.

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