Một số nền: Tôi đang viết một thuật toán tìm kiếm vũ lực nhiều hơn hoặc ít hơn để giải quyết một vấn đề mà tôi có. Để làm được điều này, tôi cần phải tạo và đánh giá tất cả các khả năng để tìm ra điều tốt nhất. Kể từ khi đánh giá thực sự mất một thời gian tôi muốn tạo ra càng ít càng tốt các giải pháp hoàn toàn bao gồm không gian tìm kiếm của tôi. Hơn nữa, càng có nhiều yếu tố tôi có thể làm điều này càng tốt. Đối với bất kỳ số K có bình thường K! hoán vị, và tạo ra tất cả chúng sẽ khó cho số cao hơn ~ 10.hoán vị duy nhất không lặp lại nhân đôi hoặc vòng tròn
Bất vấn đề: Không gian tìm kiếm nên chứa tất cả các hoán vị của hai yếu tố (N lần el1 và M lần el2, trong đó K = M + N), với những hạn chế:
- họ phải là duy nhất (tức là tôi chỉ muốn [aabbb] một lần)
- Tôi không cần đảo ngược bất kỳ hoán vị nào (ví dụ: nếu tôi có [aab], tôi cũng không cần [baa])
- Tôi xem xét các hoán vị sẽ là tròn, do đó [aab] = [aba] = [baa]
Nếu tôi có thể làm điều này, số lượng khả năng sẽ giảm đáng kể. Vì K sẽ lý tưởng là lớn, đầu tiên không thể tạo ra tất cả các hoán vị và sau đó lọc chúng theo các tiêu chí này. Tôi đã thực hiện hạn chế đầu tiên (xem bên dưới) và nó cắt giảm số từ 2^K cho hàm hoán vị bình thường của Matlab (perms) thành K!/N! M !, đó là một chiến thắng lớn. Hạn chế thứ hai sẽ chỉ cắt giảm số lượng khả năng trong một nửa (trong trường hợp tốt nhất), nhưng tôi nghĩ rằng thứ ba cũng sẽ có thể thực sự cắt giảm số lượng khả năng.
Nếu có ai biết cách thực hiện, và tốt nhất là cách tính số lượng khả năng sẽ có, điều đó sẽ giúp ích cho tôi rất nhiều! Tôi thích một lời giải thích, nhưng mã cũng tốt (tôi có thể đọc các ngôn ngữ như C, Java (Script), Python, Ruby, Lisp/Scheme).
Đối với các quan tâm: Đây là thuật toán cho việc hoán vị chỉ duy nhất mà tôi có cho đến nay:
function genPossibilities(n, m, e1, e2)
if n == 0
return array of m e2's
else
possibilities = genPossibilities(n-1, m, e1, e2)
for every possibility:
gain = number of new possibilities we'll get for this smaller possibility*
for i in max(0,(m+n-gain))
if possibility(i) is not e1
add possiblity with e1 inserted in position i
return new possibilities
- Nếu bạn có tất cả các hoán vị cho N-1 và M, sau đó bạn có thể sử dụng chúng để tìm các hoán vị cho N và M bằng cách chèn e1 vào chúng. Bạn không thể chỉ chèn ở khắp mọi nơi mặc dù, bởi vì sau đó bạn sẽ nhận được bản sao. Tôi không biết tại sao nó lại hoạt động, nhưng bạn có thể tính số lượng khả năng mới mà bạn sẽ tạo ra từ một cái cũ (tôi gọi đây là 'gain'). Con số này bắt đầu tại M + 1 cho hoán vị cũ đầu tiên và giảm một cho mỗi hoán vị cũ cho đến khi nó trở thành 0, tại thời điểm nó quay trở lại M, vv (chỉ hoạt động nếu M> = N). Vì vậy, nếu bạn muốn tính toán hoán vị cho N = 3 và M = 3 và bạn có 10 hoán vị cho N = 2 và M = 3, lợi ích của chúng sẽ là [4 3 2 1 3 2 1 2 1 1]. Trừ đi độ lợi này từ độ dài của hoán vị và bạn nhận được chỉ mục mà tại đó bạn có thể bắt đầu chèn các phần tử mới mà không tạo các bản sao.
Ông muốn k-tuples gồm 2 phần tử chứ không phải các phần tử k. Vì vậy, 2^k là chính xác. – job
Cảm ơn bạn đã trả lời. Trên thực tế, các bước 1-3 là lần thử đầu tiên của tôi, nhưng chúng sẽ tạo ra tất cả khả năng 2^k. Phần còn lại dường như không hiệu quả lắm. Tôi vẫn phải làm một cái gì đó cho tất cả các khả năng 2^k và có thêm công việc quan trọng (cho mỗi người tôi cần phải nhân bản và thay đổi nó một vài lần, sau đó sắp xếp kết quả và so sánh nó với một số nhật ký lớn mà tôi có để giữ). – Jordi