Permutações de uma matriz em Java
1. Introdução
Neste artigo, veremos como criar permutações de uma matriz.
Primeiro, vamos definir o que é uma permutação. Em segundo lugar, veremos algumas restrições. E terceiro,we’ll look at three ways to calculate them: recursively, iteratively, and randomly.
Vamos nos concentrar na implementação em Java e, portanto, não entraremos em muitos detalhes matemáticos.
2. O que é uma permutação?
A permutação de um conjunto é um rearranjo de seus elementos. Um conjunto que consiste em elementosn tem permutaçõesn!. Aquin! é o fatorial, que é o produto de todos os inteiros positivos menores ou iguais an.
2.1. Exemplo
A matriz de números inteiros [3,4,7] possui três elementos e seis permutações:
n! = 3! = 1 x 2 x 3 = 6
Permutações: [3,4,7]; [3,7,4]; [4,7,3]; [4,3,7]; [7,3,4]; [7,4,3]
3. Algoritmos
3.1. Algoritmo Recursivo
O primeiro algoritmo que examinamos éHeap’s algorithm. It’s a recursive algorithm which produces all permutations by swapping one element per iteration.
A matriz de entrada será modificada. Se não quisermos isso, precisamos criar uma cópia do array antes de chamar o método:
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);
}
}
O método usa dois métodos auxiliares:
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]);
}
}
Aqui, escrevemos o resultado emSystem.out; no entanto, podemos facilmente armazenar o resultado em uma matriz ou em uma lista.
3.2. Algoritmo Iterativo
O algoritmo do Heap também pode ser implementado usando iterações:
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. Permutações em ordem lexicográfica
Se os elementos forem comparáveis, podemos gerarpermutations sorted by the natural order dos elementos:
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));
}
}
Este algoritmo tem uma operaçãoreverse em cada iteração e, portanto, é menos eficiente em matrizes do que o algoritmo de Heap.
3.4. Algoritmo Aleatório
Sen for grande, podemosgenerate a random permutation embaralhando a matriz:
Collections.shuffle(Arrays.asList(elements));
Podemos fazer isso várias vezes para gerar uma amostra de permutações.
Podemos criar as mesmas permutações mais de uma vez, no entanto, para grandes valores den, as chances de gerar a mesma permutação duas vezes são baixas.
4. Conclusão
Existem muitas maneiras de gerar todas as permutações de uma matriz. Neste artigo, vimos o algoritmo de Heap recursivo e iterativo e como gerar uma lista classificada de permutações.
Não é viável gerar todas as permutações para grandes matrizes, portanto, podemos gerar permutações aleatórias.
A implementação de todos os trechos de código neste artigo pode ser encontrada em nossoGithub repository.