Permutasi Array di Jawa

1. Pengenalan

Dalam artikel ini, kita akan melihat bagaimana membuat permutasi array.

Pertama, kita akan menentukan apa itu permutasi. Kedua, kita akan melihat beberapa kekangan. Dan ketiga, kita akan melihat tiga cara untuk menghitungnya: secara berulang, berulang, dan secara rawak.

Kami akan menumpukan pada pelaksanaan di Java dan oleh itu tidak akan membahas banyak perincian matematik.

2. Apa itu Permutasi?

Permutasi satu set adalah penyusunan semula elemennya. Satu set yang terdiri daripada n elemen mempunyai n! permutasi. Di sini n! adalah faktorial, yang merupakan produk dari semua bilangan bulat positif yang lebih kecil atau sama dengan n .

2.1. Contohnya

Susunan bilangan bulat [3,4,7] mempunyai tiga elemen dan enam permutasi:

n! = 3! = 1 x 2 x 3 = 6

Permutasi: [3,4,7]; [3,7,4]; [4,7,3]; [4,3,7]; [7,3,4]; [7,4,3]

2.2. Kekangan

Bilangan permutasi meningkat dengan cepat dengan n . Walaupun hanya memerlukan beberapa saat untuk menghasilkan semua permutasi sepuluh elemen, akan memerlukan dua minggu untuk menghasilkan semua permutasi 15 elemen:

3. Algoritma

3.1. Algoritma Rekursif

Algoritma pertama yang kita lihat adalah algoritma Heap. Ini adalah algoritma rekursif yang menghasilkan semua permutasi dengan menukar satu elemen setiap lelaran.

Susunan input akan diubah. Sekiranya kita tidak menginginkannya, kita perlu membuat salinan susunan sebelum memanggil kaedah:

public static  void printAllRecursive( int n, T[] elements, char delimiter) { if(n == 1) { printArray(elements, delimiter); } else { for(int i = 0; i < n-1; i++) { printAllRecursive(n - 1, elements, delimiter); if(n % 2 == 0) { swap(elements, i, n-1); } else { swap(elements, 0, n-1); } } printAllRecursive(n - 1, elements, delimiter); } } 

Kaedah ini menggunakan dua kaedah penolong:

private void swap(T[] input, int a, int b) { T tmp = input[a]; input[a] = input[b]; input[b] = tmp; }
private void printArray(T[] input) { System.out.print('\n'); for(int i = 0; i < input.length; i++) { System.out.print(input[i]); } } 

Di sini, kami menulis hasilnya ke System.out , bagaimanapun, kami dapat menyimpan hasilnya dengan mudah dalam array atau dalam senarai sebagai gantinya.

3.2. Algoritma Iteratif

Algoritma Heap juga dapat dilaksanakan menggunakan lelaran:

int[] indexes = new int[n]; int[] indexes = new int[n]; for (int i = 0; i < n; i++) { indexes[i] = 0; } printArray(elements, delimiter); int i = 0; while (i < n) { if (indexes[i] < i) { swap(elements, i % 2 == 0 ? 0: indexes[i], i); printArray(elements, delimiter); indexes[i]++; i = 0; } else { indexes[i] = 0; i++; } } 

3.3. Permutasi dalam Urutan Leksikografi

Sekiranya elemen dapat dibandingkan, kita boleh menghasilkan permutasi yang disusun mengikut susunan semula jadi elemen:

public static 
    
      void printAllOrdered( T[] elements, char delimiter) { Arrays.sort(elements); boolean hasNext = true; while(hasNext) { printArray(elements, delimiter); int k = 0, l = 0; hasNext = false; for (int i = elements.length - 1; i > 0; i--) { if (elements[i].compareTo(elements[i - 1]) > 0) { k = i - 1; hasNext = true; break; } } for (int i = elements.length - 1; i > k; i--) { if (elements[i].compareTo(elements[k]) > 0) { l = i; break; } } swap(elements, k, l); Collections.reverse(Arrays.asList(elements).subList(k + 1, elements.length)); } } 
    

Algoritma ini mempunyai operasi terbalik dalam setiap lelaran dan oleh itu ia kurang cekap pada tatasusunan daripada algoritma Heap.

3.4. Algoritma Rawak

Sekiranya n besar, kita boleh menghasilkan permutasi rawak dengan mengacak susunan:

Collections.shuffle(Arrays.asList(elements));

Kita boleh melakukan ini beberapa kali untuk menghasilkan contoh permutasi.

Kami mungkin membuat permutasi yang sama lebih dari sekali, namun, untuk nilai n yang besar , kemungkinan untuk menghasilkan permutasi yang sama dua kali rendah.

4. Kesimpulan

Terdapat banyak cara untuk menghasilkan semua permutasi array. Dalam artikel ini, kami melihat algoritma Heap yang berulang dan berulang dan bagaimana menghasilkan senarai permutasi yang disusun.

Tidak mungkin untuk menghasilkan semua permutasi untuk tatasusunan besar, oleh itu, kita boleh menghasilkan permutasi rawak sebagai gantinya.

Pelaksanaan semua coretan kod dalam artikel ini terdapat di repositori Github kami.